两者可以同时执行吗?
不是同时,不——浏览器中的 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
处理程序的通知,即使我说可以继续离开。我预计这可能是因为否则,一个足够烦人的页面可能只会注册一堆处理程序并不断唠叨用户留在页面上。
在(一个)问题之后,如果我允许继续导航,我会收到两个卸载消息。