在JavaScript中捕获弹出窗口的关闭事件

xia*_*012 57 javascript dom-events

我需要在弹出窗口(使用window.open)关闭之前执行一些操作.

类似的东西会很好:

var new_window = window.open('some url')
new_window.onBeforeUnload = function(){ my code}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

glo*_*tho 77

只要弹出窗口URL与父页面位于同一域中,您的示例就会起作用,并且您将事件更改为全部小写:

var new_window = window.open('some url')
new_window.onbeforeunload = function(){ /* my code */ }
Run Code Online (Sandbox Code Playgroud)

  • 您可以做的最好的事情是在您的域中打开一个文档,然后在iframe中加载远程URL,或者通过服务器脚本读取它并从那里呈现它. (12认同)
  • 如果新打开的窗口与父窗口不在同一个域中,该怎么办?有什么黑客攻击吗? (5认同)
  • 这实际上不是检测窗口已关闭的准确方法.每当窗口中的文档被卸载时,就会触发unload和beforeunload事件,这可能是由于重定向或重新加载.有关准确的方法,请参阅@ DustinHoffner的答案(/sf/answers/3376808991/). (3认同)

Dus*_*ner 44

虽然接受的答案对于相同的起源是正确的,但我找到了一个跨源弹出窗口的解决方案:

var win = window.open('http://www.google.com'); 
var timer = setInterval(function() { 
    if(win.closed) {
        clearInterval(timer);
        alert('closed');
    }
}, 1000);
Run Code Online (Sandbox Code Playgroud)

资料来源:atashbahar.com

对于那些考虑使用它的人.

甚至Facebook也在他们的Javascript SDK中使用这种"黑客" .

您可以通过查看其代码来验证这一点.只需.closedhttps://connect.facebook.net/en_US/sdk.js中搜索即可.

  • 好一个.谢谢! (3认同)
  • 我不相信这是一个特殊的交叉起源黑客,它实际上是检测窗口关闭的唯一准确方法.每当窗口中的文档被卸载时,就会触发unload和beforeunload事件,这可能是由于重定向或重新加载,因此并不一定意味着窗口已关闭. (2认同)
  • 我刚刚使用 Edge(2021 年 3 月)测试了该解决方案,其中我正在监视同一域的窗口关闭事件,即在我的应用程序中打开然后关闭的其他窗口,这效果很好! (2认同)
  • 这种方法对我有用,但是即使打开的窗口(win)内的 URL 发生更改, win.close 也会设置为 true 。有没有办法避免它并且只在胜利真正结束时才执行?@达斯汀霍夫纳 (2认同)

val*_*nas 13

事件名称是onbeforeunloadonBeforeUnload.JS区分大小写.

  • 如果我们通过使用它附加事件将其作为内联属性附加到html并且html区分大小写这意味着这绝对没有区别 (2认同)

ran*_*ame 5

onbeforeunload打开事件后,需要将事件绑定到窗口。

最简单的方法是在窗口源代码中包含javascript onbeforeunload代码。

有关详细说明,请在此处此处在Stackoverflow上参考这两个非常相似的问题。


Rez*_*eza 5

onbeforeunload必须在加载弹出窗口添加事件。例如,您可以将其添加到加载事件的末尾,如下所示;

const new_window = window.open('some url')
new_window.onload = function(){ 
    /* my code */ 
    this.onbeforeunload = function(){ /* my code */ }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*gin 5

您可能不想覆盖 的值onbeforeunload,因为如果弹出窗口也使用该挂钩,这会干扰弹出窗口的处理程序。

addEventListener('beforeunload', ...)代替使用。

const wnd = window.open(theUrl)
wnd.addEventListener('beforeunload', () => {
  // do stuff
})
Run Code Online (Sandbox Code Playgroud)

请注意,事件还存在其他选项,例如unloadpageHide。阅读文档以了解什么事件最适合您的实施。

以供参考:

https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event

https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event

https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event

有关页面生命周期的概述,请参阅:

https://developers.google.com/web/updates/2018/07/page-lifecycle-api#developer-recommendations-for-each-state