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

7
我有一个打开多个窗口的网络应用程序。我的问题是当父窗口关闭/刷新时,子窗口仍然保持打开状态。 我尝试使用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(最新版本)。


1
"我尝试使用 onunload 和 onbeforeunload,但是它们都无法捕获窗口关闭事件(在 Chrome 和 Firefox 中)。""onbeforeunload 在 Firefox 和 Chrome 中绝对可以工作。" - T.J. Crowder
none of them [caught] the window close event”这个事实表明您的代码存在问题,因为正如T.J. Crowder所指出的那样,它们在这些命名的浏览器中是有效的。您能否展示一下您的尝试,然后我们可能能够提供帮助。 - David Thomas
这段代码似乎在Chrome上可以运行,但在Firefox和IE上无法正常工作。在这些事件之外测试了closeAll函数,它可以正常工作。我还在SO上找到了多个参考,表明它在Firefox和其他浏览器上无法正常工作。https://dev59.com/smUq5IYBdhLWcg3wQ-Tk https://dev59.com/S3rZa4cB1Zd3GeqP4qDf - flaviu
4个回答

7
请使用此代码。
var popup = window.open("popup.html", "popup", "width=200,height=200");

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

我有一个窗口数组,并调用closeAll()函数,我认为我的代码与你的解决方案类似,但它只在Chrome中工作。发现了关于除Chrome之外的其他浏览器的响应https://dev59.com/smUq5IYBdhLWcg3wQ-Tk,所以我不知道你的解决方案是否跨浏览器。 - flaviu

3
如果您使用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
如果目标是在父窗口关闭或刷新时关闭子窗口,而不是实际检测事件,您可以使用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);
            });

2

我找到了一个适用于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
1
@clarifier 这可能是因为 closeAll() 函数需要遍历所有弹出窗口对象实例并调用它们的 close() 方法。 - Kevin Ghadyani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接