el's blog

A noder, FEer. use express, vue...etc

Js 关闭当前页面
因为浏览器限制,window.close() 不能直接关闭当前页面了。

场景

以前见到过一个当你保存某表单成功后,显示倒计时并自动关闭页面的效果,现在终于轮到我来实现了。

不过这有何好说,直接调用下面的代码不就关闭了么?

1
window.close()

然而,在最新的 chrome 浏览器上写上却是显示一个警告并且代码并不生效。

1
Scripts may close only the windows that were opened by it.

翻了好多资料却都于事无补。

close函数的限制

上面出现的警告信息我在 stackoverflow 上看到有人回答

If your script did not initiate opening the window (with something like window.open), then the script in that window is not allowed to close it. Its a security to prevent a website taking control of your browser and closing windows.

简而言之,window.close() 是有限制的,window.open 会返回一个对象,这个对象就是打开的新页面的 window 对象,

在 pageA 中写入

1
2
let pageB = window.open('xxx pageB');
pageB.close();

这就可以看见关闭了新打开的 pageB 页面。

跨页面通信

然而我们在前一个页面却不知道下一个页面的变化,比如上面例子我们不知道新打开的 pageB 页面到底做了什么,pageA 页面就不知道何时才能关闭 pageB。

这时候就需要用上 postMessage 跨页面通信。

在 pageA 上写上监听

1
2
3
window.addEventListener('message', (event) => {
console.log('this is a message');
}, false);

在 pageB 上可以发送 postMessage

1
window.opener.postMessage('close', '*');

在 pageA 上打开 pageB 后就能在控制台上看到 pageA 控制台打印出了 this is a message

完整代码

pageA

1
2
3
4
5
window.addEventListener('message', (event) => {
if (event.data === 'close') {
event.source.top.close();
}
}, false);

pageB

1
window.top.opener.postMessage('close', '*');

当然,如果考虑 iframe 中会比较复杂,所以才用了 window.top。