多个onbeforeunload()和onunload()事件

时间:2010-05-12 14:37:19

标签: javascript javascript-events onbeforeunload

我从客户端遇到一个奇怪的问题,我们的代码包括使用onbeforeunload()来触发对话框,但是它们还包括另一个公司代码,它们也绑定了这个事件处理程序。

两者可以同时执行吗?

我一直在阅读这篇文章,http://oreilly.com/catalog/9780596101992“JavaScript:The Definitive Guide,Fifth Edition”试图帮助更好地理解浏览器内部和javascript堆栈中发生的事情,但它证明了这一点。

我从阅读本书中了解到,如果使用Level 2 API addEventListener()附加某些事件,则可以同时执行某些事件,但顺序将由浏览器完成。但是没有提到onbeforeunload()事件。只是onunload()。

这引导我进入问题的第二部分。如果在onbeforeunload()中触发了一个事件,我认为除非它返回true,否则永远不会调用onunload()?

如果有人可以对它有所了解,或者给我一个很好的教程/指南,或者将多个事件处理程序分配给同一个事件,或者特别是这两个事件就是ace。

由于

1 个答案:

答案 0 :(得分:8)

  

两者是否可以同时执行?

不是字面上同时,没有 - 浏览器中的Javascript(目前)是单线程的。因此onbeforeunload事件可能有多个处理程序,但它们将被串行调用,而不是同时调用。至少在理论上;在实践中,看起来只有其中一个被调用(见下文)。

  

如果在onbeforeunload()中触发了一个事件,我认为除非它返回true,否则永远不会调用onunload()?

如果任何onbeforeunload处理程序取消卸载,则不会调用onunload处理程序。通过执行两项操作来取消卸载(因为浏览器在这里有所不同):首先,将字符串分配给returnValue对象的event属性,然后将该字符串从函数中返回。详情herehere。 (该字符串用作提示,允许用户决定是否取消卸载。)

快速测试

理论上,我们来看看实际发生了什么:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
    font-family: sans-serif;
}
</style>
<script type='text/javascript'>
window.onload = pageInit;
function pageInit() {
    hook(window, 'beforeunload', beforeUnload1);
    hook(window, 'beforeunload', beforeUnload2);
    hook(window, 'unload', unload1);
    hook(window, 'unload', unload2);
}

function beforeUnload1(event) {
    var s;

    event = event || window.event;
    s = "Message from beforeUnload1";
    event.returnValue = s
    return s;
}

function beforeUnload2(event) {
    var s;

    event = event || window.event;
    s = "Message from beforeUnload2";
    event.returnValue = s
    return s;
}

function unload1(event) {
    alert("Message from unload1");
}

function unload2(event) {
    alert("Message from unload2");
}

var hook = (function() {
    var d;

    function hookViaAttachEvent(obj, eventName, handler) {
        obj.attachEvent('on' + eventName, handler);
    }
    function hookViaAddEventListener(obj, eventName, handler) {
        obj.addEventListener(eventName, handler, false);
    }

    d = document.createElement('span');
    if (d.addEventListener) {
        return hookViaAddEventListener;
    }
    else if (d.attachEvent) {
        return hookViaAttachEvent;
    }
    throw "Neither attachEvent nor addEventListener found.";
})();
function hook(eventName, handler) {

}
</script>
</head>
<body></body>
</html>

在Chrome,IE和Firefox上,我只看到其中一位onbeforeunload处理程序的通知,即使我说可以继续离开。我希望这可能是因为否则,一个充满刺激性的页面可能只是注册了一堆处理程序并且一直唠叨用户留在页面上。

在(一)个问题之后,如果我允许导航继续,我会收到两个卸载消息。