【问题标题】:is it possible to open a popup with javascript and then detect when the user closes it?是否可以使用 javascript 打开一个弹出窗口,然后检测用户何时关闭它?
【发布时间】:2011-03-18 12:42:19
【问题描述】:

问题几乎都在标题中。

是否可以(以及如何?)使用 javascript 打开一个弹出窗口,然后检测用户何时关闭它?

我在项目中使用 jquery,所以 jquery 解决方案会很好。干杯!

【问题讨论】:

  • 定义“弹出”。我们是在谈论某种页面上呈现的模态框吗?一个JavaScript警报?新的浏览器窗口?
  • 一个新的浏览器窗口...抱歉我不够清晰

标签: javascript jquery popup


【解决方案1】:

如果您可以控制弹出窗口的内容,则在那里处理窗口的unload 事件并通过opener 属性通知原始窗口,首先检查打开器是否已关闭。请注意,这在 Opera 中并不总是有效。

window.onunload = function() {
    var win = window.opener;
    if (!win.closed) {
        win.someFunctionToCallWhenPopUpCloses();
    }
};

由于unload 事件将在用户离开弹出窗口中的页面时触发,而不仅仅是在窗口关闭时触发,您应该检查弹出窗口是否在someFunctionToCallWhenPopUpCloses 中实际关闭:

var popUp = window.open("popup.html", "thePopUp", "");
function someFunctionToCallWhenPopUpCloses() {
    window.setTimeout(function() {
        if (popUp.closed) {
            alert("Pop-up definitely closed");
        }
    }, 1);
}

如果您无法控制弹出窗口的内容,或者如果您的目标浏览器之一不支持unload 事件,您将只能在主窗口中使用某种轮询解决方案。调整间隔以适应。

var win = window.open("popup.html", "thePopUp", "");
var pollTimer = window.setInterval(function() {
    if (win.closed !== false) { // !== is required for compatibility with Opera
        window.clearInterval(pollTimer);
        someFunctionToCallWhenPopUpCloses();
    }
}, 200);

【讨论】:

  • 我推荐轮询解决方案而不是unload事件,因为它兼容更多的浏览器(见opera-bugs.jottit.com)。
  • @JonathonHill:同意。我在答案的前面提到了 Opera 问题,但我应该更清楚地说明这一点。感谢您的编辑。顺便说一句,在 Opera 中要求 window.closed !== false 的原因是什么?
  • 这是 Opera 中的一个错误的解决方法。我是从opera-bugs.jottit.com 发现的。
  • @JonathonHill:是的,我阅读了该页面。我希望有更多的细节。放心,我会查的。
  • 无论如何,如果使用轮询选项,请绝对不要忘记window.clearInterval() 调用。如果不包括在内,原始页面将继续轮询……一遍又一遍……
【解决方案2】:

您的问题有一个非常简单的解决方案。

首先创建一个新对象,它会像这样打开一个弹出窗口:

var winObj = window.open('http://www.google.com','google','width=800,height=600,status=0,toolbar=0');

为了知道此弹出窗口何时关闭,您只需使用如下循环继续检查:

var loop = setInterval(function() {   
    if(winObj.closed) {  
        clearInterval(loop);  
        alert('closed');  
    }  
}, 1000); 

现在你可以用你想要的任何 javascript 代码替换 alert。

玩得开心! :)

【讨论】:

    【解决方案3】:

    尝试查看unloadbeforeunload 窗口事件。监视这些应该让您有机会通过以下方式在窗口关闭时 DOM 卸载时回调:

    var newWin = window.open('/some/url');
    newWin.onunload = function(){
      // DOM unloaded, so the window is likely closed.
    }
    

    【讨论】:

    • 感谢 ajm 看起来很棒。无论如何,是否有机会获得弹出窗口的网址?
    • 这不会跨浏览器工作。您需要在弹出窗口中处理unload 事件。
    • Unload 在每个新请求时触发,而不仅仅是在窗口关闭时触发。
    • 是的,YMMV 已卸载。您可能需要结合使用 unload 和 beforeunload 来覆盖 IE。 @Josh - 每当子窗口的 Document 独立于请求从浏览器卸载时,都应该触发 Unload;你看到了什么行为?
    • 例如,如果弹出窗口中有超链接,点击它们会触发unload
    【解决方案4】:

    如果你可以使用jQuery UI Dialog,它实际上有一个close事件。

    【讨论】:

    • jQuery 并不是所有问题的解决方案 :)。
    • 真的,真的。我应该在“如果你可以使用 jQuery UI 对话框”中用“如果”这个词开始我的回答,而不仅仅是 假设 这是可能的。嘿!等一下……
    • 而且,就 JavaScript 而言,jQuery 从来都不是真正的问题解决方案,而是一个巨大的、巨大的、HUGE 解决方案的捷径,无论它可能是什么.您可以通过风景优美的路线了解更多信息,但在许多情况下,我和大多数人更喜欢 (huge, HUGE, HUGE ) jQuery 快捷方式。
    【解决方案5】:

    打开一个新窗口调用:

    var wnd = window.open("file.html", "youruniqueid", "width=400, height=300");
    

    如果您只想知道该窗口何时关闭,请使用onunload

    wnd.onunload = function(){
        // do something
    };
    

    如果您想在关闭之前得到用户的确认,请使用onbeforeunload

    wnd.onbeforeunload = function(){
        return "are you sure?";
    };
    

    【讨论】:

    • 这不会跨浏览器工作。您需要处理弹出文档中的unload事件。
    • Unload 在每个新请求时触发,而不仅仅是在窗口关闭时触发。
    【解决方案6】:

    我们在我的一个工作项目中这样做。

    诀窍是在你的父页面中有一个 JS 函数,你计划在弹出窗口关闭时调用它,然后在弹出窗口中挂钩 unload 事件。

    window.opener 属性指的是产生此弹出窗口的页面。

    例如,如果我在原始页面上编写了一个名为 callingPageFunction 的函数,我会从弹出窗口中这样调用它:

    $(window).unload(function() {
        window.opener.callingPageFunction()
    });
    

    两个音符:

    1. 这应该包含在一个就绪函数中。
    2. 我有一个匿名函数,因为您可能需要其中的其他逻辑

    【讨论】:

      【解决方案7】:

      我认为最好的方法是:

      const popup = this.window.open(url.toString());
      popup.addEventListener('unload', ()=> console.log('closed'))
      

      【讨论】:

        【解决方案8】:

        是的,处理弹出窗口的 onbeforeUnload 事件,然后在父窗口上调用函数:

        window.opener.myFunction()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-05-02
          • 2023-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多