我的场景有点复杂,但我可以在下面的示例中很快重现我的问题:
<html>
<head>
<script type="text/javascript">
function fnUnloadHandler() {
alert("Unload event.. session termination request to be sent to server");
}
function f() {
i = 1;
while(1==1){
i++;
}
}
</script>
</head>
<body onbeforeunload="fnUnloadHandler()">
<p><button href="#" onClick="f();" >do</button></p>
</body>
</html>
现在;单击“执行”按钮后,f() 将浏览器置于无限循环中。在那段时间里,如果我关闭页面,我会得到两种不同的行为:
- 在 IE7 上:Javascript 执行终止,触发 onbeforeunload 事件并显示警报,然后页面关闭。
- 在 IE9 上:Javascript 执行终止,onbeforeunload 事件NOT 触发,NO 显示警告并直接关闭页面。<
我想知道为什么 IE9 在这种情况下没有正确处理 onbeforeunload ..是否有任何修复/补丁适用于 IE9 来解决这个问题?
非常感谢!
费拉斯
最佳答案
JavaScript 至少大部分(如果不是全部)实现是单线程的。如果您调用包含无限循环的 f
函数,则表示一个 JS 线程正忙。 onbeforeunload
处理程序已排队,当函数 f
返回时将调用它。不幸的是,f
永远不会返回。但是,某些实现会采用 while(1==1)
等构造,并将终止该循环,因为它不会去任何地方。 IE 经常向您显示一个 conform
警报,提示类似“脚本正在运行,但看起来没有任何进展,是否要终止它?”
从逻辑上讲,调用 onbeforeunload
处理程序的唯一原因是,如果未调用 f
函数,或者特定浏览器的实现获胜遇到错误时不要只是放弃调用队列,处理程序仍将被调用。
顺便说一句,一些代码审查:
function f()
{
i = 1;
}
正在创建一个邪恶的隐含全局变量,将其更改为:
function f()
{
var i = 1;
}
避免弄乱全局命名空间。此外,onbeforeunload
事件通常附加到全局对象,以免您想处理特定元素的卸载。如果要处理全局卸载(客户端离开页面),IE7 和 IE8 将泄漏内存,check the solution here ,该代码示例展示了如何使用附加到全局对象的事件处理程序来避免内存泄漏。
关于javascript - 在 Javascript 运行期间关闭页面时不执行 onbeforeunload 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20188653/