在Javascript运行期间关闭页面时未执行onbeforeunload事件

时间:2013-11-25 09:34:17

标签: javascript html internet-explorer internet-explorer-9 onbeforeunload

我的场景有点复杂,但我可以在以下示例中重现我的问题:

<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执行终止,触发onb​​eforeunload事件并显示警告,然后关闭页面。
  • 在IE9上:Javascript执行终止,onbeforeunload事件 NOT 触发, NO 警告显示并直接关闭页面。

我想知道为什么IE9在这种情况下没有正确处理onbeforeunload ..是否有任何修复/补丁适用于IE9来解决这个问题?

非常感谢提前!

Firas

2 个答案:

答案 0 :(得分:2)

JavaScript至少大部分(如果不是全部)实现都是单线程的。如果你调用包含无限循环的f函数,那一个JS线程就忙了。 onbeforeunload处理程序排队,并在函数f返回时调用它。不幸的是,f永远不会回来。但是,有些实现会接受像while(1==1)这样的构造,并会终止该循环,因为它不会去任何地方。 IE通常会向您显示conform警报,说明“脚本正在运行,并且看起来不像任何地方,你想要终止它吗?”

逻辑上唯一的原因是onbeforeunload处理程序被调用的原因是,如果没有调用f函数,或者特定浏览器的实现不会放弃调用遇到错误时队列,并且仍然会调用处理程序 作为一个助手,一些代码审查:

function f()
{
    i = 1;
}

正在创建 evil 隐含的全局变量,将其更改为:

function f()
{
    var i = 1;
}

以避免混乱全局命名空间。此外,onbeforeunload事件通常附加到全局对象,以免您想要处理特定元素的卸载。如果你想处理一个全局卸载(客户端离开页面),IE7和IE8将泄漏内存check the solution here,该代码示例显示了如何通过附加到事件处理程序的内存处理程序来避免泄漏内存全球对象。

答案 1 :(得分:1)

请参阅此链接http://msdn.microsoft.com/en-us/library/ie/ms536907%28v=vs.85%29.aspx我希望这会对您有所帮助

<!DOCTYPE html>
<html>
<head>
<script>
  function closeIt()
  {
    return "any string";
  }
  window.onbeforeunload = closeIt;
</script>
</head>
<body>
  <a href="http://www.microsoft.com">Click here to navigate to 
      www.microsoft.com</a>
</body>
</html>