5

我有一个来自客户的奇怪问题,我们的代码包括用于onbeforeunload()触发对话的代码,但它们还包括另一个公司代码,该代码也绑定了此事件处理程序。

两者可以同时执行吗?

我一直在阅读这篇文章, http: //oreilly.com/catalog/9780596101992 “JavaScript:权威指南,第五版”,试图帮助更好地理解浏览器内部和 Javascript 堆栈中发生的事情,但事实证明它相当头脑弯曲。

我通过阅读本书了解到,如果使用 Level 2 API 附加某些事件,则可以同时执行它们,addEventListener()但顺序将取决于浏览器。然而,没有提及该onbeforeunload()事件。只是onunload().

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

如果有人可以对此有所了解,或者为我提供一个很好的教程/指南,关于将多个事件处理程序分配给同一事件,或者特别是这两个事件,这将是王牌。

4

1 回答 1

8

两者可以同时执行吗?

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

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

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

快速测试

理论讲了这么多,让我们看看实际发生了什么:

<!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处理程序的通知,即使我说可以继续离开。我预计这可能是因为否则,一个足够烦人的页面可能只会注册一堆处理程序并不断唠叨用户留在页面上。

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

于 2010-05-12T14:42:05.450 回答