【问题标题】:Why does my popup window lose its event beforeunload after a reload?为什么我的弹出窗口在重新加载后会在卸载前丢失其事件?
【发布时间】:2026-02-11 01:30:01
【问题描述】:

我有一个小应用程序可以打开一个新的弹出窗口。我将窗口存储在一个变量中:

popup = window.open("sites/display.html", "_blank");

之后我添加了一个 beforeunload 事件监听器:

$(popup).on('beforeunload', function(){
    // Do something
});

然后我稍后用一个按钮重新加载窗口:

popup.location = popup.location;

之后,如果我关闭窗口,则不会再触发 Event beforeunload。我认为这与重新加载有关,因为如果我不重新加载页面,一切正常。

如何解决这个问题,以便在每次窗口关闭时触发事件?

我使用的确切代码:

function startClock(allowRestart) {
    saveSettings(allowRestart);
    if ($("#separated-display").is(":checked")) {
        // Separated mode activated
        if (popup == undefined) {
            openPopup();
        } else {
            if (popup.closed) {
                openPopup();
            }else{
                popup.location.reload();
            }
        }
    } else {
        // Separated mode deactivated
        if (popup != null && popup.closed == false) {
            $(popup).unbind();
            popup.close();
        }
        window.location = "sites/display.html"; // Open the clock in same window
    }
}

function openPopup(){
    // Open new popup window
    popup = window.open("sites/display.html", "_blank");

    // TO-DO: Fix event not fired after 1. window reload 2. window close
    popup.addEventListener('beforeunload', function(){
        console.log("unload");
    });
}

【问题讨论】:

  • 查看控制台。我确定您会收到类似“来自...的访问被拒绝”的错误
  • 实际上一切正常。控制台中没有错误。它是我的一个 html 文件的弹出窗口,因此符合同源策略。
  • 你是打开同域的窗口还是跨域?

标签: javascript jquery event-handling window


【解决方案1】:

当您尝试使用 window.open() 访问相同的来源(使用相对路径)窗口时,不应显示访问错误。

popup = window.open("/sites/display.html", "_blank")

popup 变量将引用新创建的窗口,它是一个表示WindowProxy 对象的薄包装器,它确实具有window 的所有功能。

当页面重新加载时,一切都设置为默认值,并且窗口失去了之前设置的属性。因此,之前附加的unload 事件不再附加。其他事件也会发生这种情况。

因此这里的问题是,在打开弹出窗口时该事件仅被附加到弹出窗口一次,该弹出窗口在页面重新加载时被重置。最好的方法是在 js 文件中添加 unload 事件,该文件专门加载到 sites/display.html 页面上。在那里,每当sites/display.html 页面加载时,您都可以访问新的窗口对象并在window.load / document.ready 中附加事件(根据您的用例)。

您将无法在调用页面重新加载之前或之后弹出事件,因为您当前正在执行此操作,如果您尝试在页面重新加载之前/之后设置它,该属性将被重置,因为它可能会被执行异步。

注意:

  1. 您应该使用reload() 公开的window.location 函数,而不是更新位置属性。因为更新属性不会跳过浏览器缓存。
popup.location.reload()
  1. window.open 的支持是unknown for most browsers,尽管我可以在Chrome 84 上使用它。

【讨论】:

  • 你得到所有的值了吗? 1. popup 是否有对 window 对象的引用? 2. 你能附加事件吗? 3.你是否使用了reload功能,因为在这里分配到位置不起作用?
  • 不,即使您的回答也不起作用。我在问题中添加了一些代码。
  • 感谢您到目前为止的帮助,我现在有另一个问题:如何使用仅在主窗口(而不是弹出窗口)中可用的功能?我可以使用 window.opener 吗?或者我该如何解决?
  • 在引用主窗口的 js 文件中附加主窗口特定的事件/属性。要遵循的基本规则是在该页面上保留页面特定的操作,这些操作可以在重新加载时重新附加。您可以使用标签间通信在标签之间传递消息,您可以使用本地存储/cookies。
  • 您甚至可以使用Broadcast Channel API 在窗口、选项卡、框架或 iframe 之间进行通信。
最近更新 更多