【问题标题】: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 和其他浏览器stackoverflow.com/questions/14645011/…stackoverflow.com/questions/20773306/…

标签: javascript


【解决方案1】:

使用这个

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

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

【讨论】:

  • 我有一个窗口数组,我调用了 closeAll() 函数,我认为我的代码与您的解决方案相似,但它仅适用于 Chrome。发现此响应是关于 Chrome stackoverflow.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);
                });
    

    【讨论】:

      猜你喜欢
      • 2012-12-15
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-14
      • 2011-01-19
      相关资源
      最近更新 更多