window.onbeforeunload不在子窗口中触发

时间:2009-11-13 10:48:59

标签: javascript javascript-events onbeforeunload

我想在Javascript中将一个函数绑定到子窗口的beforeunload事件。 我有以下代码:

newWind = window.open(settings.url, "Dialog", "width=" + settings.width + ",height=" + settings.height + ",resizable=" + settings.resizable + ",scrollbars=" + true);

newWind.onunload = function() { alert('test'); }

在Firefox中运行良好,但在IE7中失败。谁能看到我做错了什么?

2 个答案:

答案 0 :(得分:4)

newWind.onunload = function() { alert('test'); }

由于某种原因,IE不允许您将一个窗口上下文中的函数分配给[before] unload上的另一个窗口。您可以将外部函数分配给其他事件处理程序,包括newWind.document.body.onunload,但这不是一个好主意。

首先因为IE的垃圾收集是基于窗口的,所以如果你关闭或导航开启窗口,弹出窗口将尝试执行死函数,或者在范围内使用死变量函数,导致奇怪的JavaScript错误。

其次,因为你没有从开启者那里得知弹出文件的加载足以能够设置处理程序。在open调用之后,弹出文档可能根本没有开始加载,在这种情况下,您无法安全地在其上设置任何事件处理程序。因此在设置onunload处理程序之前需要一个短暂的延迟,用户可能会在那段时间关闭窗口。开场白不知道要拖延多久;相反,子对话框必须调回父对象,告诉它已经准备好了。最好让孩子弹出窗口负责接收自己的事件并打电话给揭幕战让它知道。

跨窗口脚本有无穷无尽的陷阱。尽量避免使用它。对于对话框,总是使用页面内元素,这些元素比窗口弹出窗口更可靠,更烦人。

答案 1 :(得分:1)

我正在使用以下hack来查找子窗口何时关闭:

function checkChildWindow(win, onclose) {
    var w = win;
    var cb = onclose;
    var t = setTimeout(function() { checkChildWindow(w, cb); }, 500);
    var closing = false;
    try {
        if (win.closed || win.top == null) //happens when window is closed in FF/Chrome/Safari
        closing = true;        
    } catch (e) { //happens when window is closed in IE        
        closing = true;
    }
    if (closing) {
        clearTimeout(t);
        onclose();
    }
}

function openWindow(url) {  
    ...
    var wnd = window.open(url, "window_name", "[...flags...]");
    checkChildWindow(wnd, function() { alert('child was closed!'); } );
    ...
}