关闭父窗口时关闭所有子窗口

Posted

技术标签:

【中文标题】关闭父窗口时关闭所有子窗口【英文标题】:Close all child windows when parent window is closed 【发布时间】:2014-10-12 12:08:44 【问题描述】:

我有一个可以打开多个窗口的 Web 应用程序。我遇到的问题是,当父窗口关闭/刷新时,子窗口仍然打开。 我试过使用onunloadonbeforeunload,但它们都没有捕捉到窗口关闭事件(在 Chrome 和 Firefox 中)。 我有一个窗口数组,但刷新后对它们的引用丢失了。

还有其他方法可以捕捉到这个事件吗?

这是我与关闭窗口相关的代码(在unloadonbeforeunload 之外运行closeAll() 会关闭我所有打开的窗口,但在页面刷新时不会关闭):

window.unload = function() 
   closeAll();

window.onbeforeunload  = function() 
   closeAll();


var closePopup = function(popup) 
   removePopup(popup);
   popup.close();
;

var closeAll = function() 
   for (var popup in _this.popups) 
       closePopup(_this.popups[popup]);
    

这仅适用于 Chrome,但不适用于 Firefox 和 IE(最新版本)。

【问题讨论】:

“我尝试过使用 onunload 和 onbeforeunload,但它们都没有捕获窗口关闭事件(在 Chrome 和 Firefox 中)” onbeforeunload 在 Firefox 和 Chrome 中绝对有效. 没有一个 [caught] the window close event”表明您的代码有问题,因为 T.J. Crowder 指出,它们确实在那些命名的浏览器中工作。你能告诉我们你的尝试吗,那么我们也许可以提供帮助。 看来这段代码可以在 Chrome 上运行,但不能在 Firefox 和 IE 上运行。在这些事件之外测试了closeAll 函数,它可以工作。我还在 SO 上找到了多个参考,它不适用于 Firefox 和其他浏览器***.com/questions/14645011/…***.com/questions/20773306/… 【参考方案1】:

使用这个

var popup = window.open("popup.html", "popup", "width=200,height=200");

window.onunload = function() 
    if (popup && !popup.closed) 
        popup.close();
    
;

【讨论】:

我有一个窗口数组,我调用了 closeAll() 函数,我认为我的代码与您的解决方案相似,但它仅适用于 Chrome。发现此响应是关于 Chrome ***.com/questions/14645011/… 以外的浏览器的,所以我不知道您的解决方案是否是跨浏览器。【参考方案2】:

如果您使用 window.open 打开所有子窗口,请在所有页面中包含此 javascript,然后从任何包含的页面中 CloseAll(false); 将关闭所有子、孙、曾孙... . 等,并将第一个(根)页面重定向到 login.aspx,并且不会干扰任何事件触发器,因为它通过了初始处理程序。

function CloseAll(bTopFound)

    if (!bTopFound && nParent != null && !nParent.closed) 
        //parent window was not closed
        nParent.CloseAll(false);
        return;
     else 
        if (nParent == null || nParent.closed)
        
            top.location = '/login.aspx';
        
    

    for (var i = 0; i < Windows.length; i++)
    
        if (!Windows[i].closed) 
            Windows[i].CloseAll(true);
        
    
    nParent = null;
    setTimeout(window.close, 150);


var Windows = [];
//override window.open to inject store child window objects
window.open = function (open) 
    return function (url, name, features) 
        // set name if missing here
        name = name || "default_window_name";
        var newWindow = open.call(window, url, name, features);
        Windows.push(newWindow);
        return newWindow;
    ;
(window.open);

var nParent = null;
window.onload = function (load) 
    return function (e) 
        nParent = window.opener;
        if (load != null) 
            load.call(e);
        
    
(window.onload);

window.onunload = function (unload) 
    return function (e) 
        //promote first branch page to parent
        if (nParent != null && !nParent.closed && Windows.length > 0) 
            nParent.Windows.push(Windows[0]);
            Windows[0].nParent = nParent;
        
        //make first child window new root
        for (var i = 1; i < Windows.length; i++) 
            Windows[i].nParent = Windows[0];
            Windows[0].Windows.push(Windows[i]);
        
        if (unload != null) 
            unload.call(e);
        
    
(window.onunload);

【讨论】:

【参考方案3】:

找到了适用于最新版本的 Chrome、Firefox 和 IE 的合适解决方案 (jQuery)。

最初想使用 jQuery $().unload() 函数 (http://api.jquery.com/unload/) 但自 1.8 (http://bugs.jquery.com/ticket/11733) 起已弃用。由于$().unload()$().bind('unload', fn) 的快捷方式,所以我尝试使用基本的,并且它有效。

$(window).on('unload', function() 
    closeAll();
);

【讨论】:

但它只是关闭父窗口,子窗口没有关闭 @clarifier 这可能是因为 closeAll() 函数需要循环遍历所有弹出窗口对象实例并在它们上调用 close()。【参考方案4】:

如果目标是在关闭或刷新父窗口时关闭子窗口,而不是实际检测事件,您可以使用 setInterval 来检测 window.opener 何时不再存在。

            function CloseOnParentClose() 
                if (typeof window.opener != 'undefined' && window.opener != null) 
                    if (window.opener.closed) 
                        window.close();
                    
                
                else 
                    window.close();
                
            
            $(window).ready(function () 
                setInterval(CloseOnParentClose, 1000);
            );

【讨论】:

以上是关于关闭父窗口时关闭所有子窗口的主要内容,如果未能解决你的问题,请参考以下文章

子窗口关闭,父窗口如何刷新

怎么实现父窗口打开子窗口,子窗口关闭后自动刷新父窗口?

firefox下如何关闭子窗口刷新父窗口? - 技术问答

父窗口刷新的问题!

C#里面,子窗口关闭以后,刷新一个父窗口的控件的属性,怎么办

在winform中,关闭窗口时刷新父窗口(原来打开此窗口的窗口)