場景
以前見到過一個當你保存某表單成功后,顯示倒計時並自動關閉頁面的效果,現在終於輪到我來實現了。
不過這有何好說,直接調用下面的代碼不就關閉了么?
window.close()
然而,在最新的 chrome 瀏覽器上寫上卻是顯示一個警告並且代碼並不生效。
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 中寫入
let pageB = window.open('xxx pageB');
pageB.close();
這就可以看見關閉了新打開的 pageB 頁面。
跨頁面通信
然而我們在前一個頁面卻不知道下一個頁面的變化,比如上面例子我們不知道新打開的 pageB 頁面到底做了什么,pageA 頁面就不知道何時才能關閉 pageB。
這時候就需要用上 postMessage 跨頁面通信。
在 pageA 上寫上監聽
window.addEventListener('message', (event) => {
console.log('this is a message');
}, false);
在 pageB 上可以發送 postMessage
window.opener.postMessage('close', '*');
在 pageA 上打開 pageB 后就能在控制台上看到 pageA 控制台打印出了 this is a message
完整代碼
pageA
window.addEventListener('message', (event) => {
if (event.data === 'close') {
event.source.top.close();
}
}, false);
pageB
window.top.opener.postMessage('close', '*');
當然,如果考慮 iframe 中會比較復雜,所以才用了 window.top。