当window.location在按钮事件中更改时,IE9 onbeforeunload调用两次...最小再现

时间:2012-04-01 20:15:01

标签: javascript html internet-explorer-9 onbeforeunload

我一直在锤击和锤击,只是无法到达任何地方。

我有一个取消按钮,执行“window.location ='404.htm';”点击时。 onbeforeunload处理程序会触发两次,但前提是用户单击“在此页面上停留”到第一个对话框。正常导航(页面刷新,转到主页)onbeforeunload处理程序仅触发一次。

我设法使用最少量的HTML和脚本重现行为:

<!DOCTYPE html>
<html>
<head>
    <title>Test page</title>
</head>
<body onbeforeunload="return 'Unsaved changes';">
    <form name="form1" id="form1">
        <input id='cmdCancel' type="button" value="Cancel" onclick="window.location = '404.htm';" />
    </form>
    <script type="text/javascript">
        /*
         * Connecting the events via code makes no difference
         *
        document.forms[0].cmdCancel.onclick =
            function () {
                alert('Clicked cancel. About to navigate...');
                window.location = '404.htm';
            };

        window.onbeforeunload = function () {
            return "Unsaved changes";
        }; 

        */   
    </script>
</body>
</html>

“onbeforeunload两次调用”有很多点击,但没有最小的再现,也没有实际的解决方案。

有什么建议吗?

谢谢!

5 个答案:

答案 0 :(得分:4)

试试这个,这对我有用。此解决方案最初由Amit发布 http://social.msdn.microsoft.com/Forums/eu/sharepointinfopath/thread/13000cd8-5c50-4260-a0d2-bc404764966d?prof=required

请记住,暂时禁用onbeforeunload并在短时间内重新启用它是关键。

var checkChangesEnabled = true;

window.onbeforeunload = confirmExit;

function confirmExit()
{
  if(checkChangesEnabled)
  {
    event.returnValue = "You have not saved your document yet.";
    disableCheck();
  }
}

function disableCheck()
{
  checkChangesEnabled = false;
  setTimeout("enableCheck()", "100");
}

function enableCheck()
{
   checkChangesEnabled = true;
}

答案 1 :(得分:0)

无论如何,你的onbeforeunload是通过JS解释的,你可能可以在全局变量中使用布尔标志来知道它是否是第一次由事件运行启动进程。像:

<head>
  ...
  <script ...>
  var flag=true;
  var ret="";
  function getoff() {
    if(flag) {
      //do your things and save your return value to the global variable "ret"
      //ret="Unsaved changes";
      flag=false; //with this, the code above will be executed only once
    }
    return ret; //the second call will return the same thing as the first call, as first call's return value is stored in a global variable, and is not modified during the second call
  }
  </script>
</head>
<body onbeforeunload="return getoff();">
...

另一种可能性,根据this post问题似乎来自使用JS更改页面,您可以使用隐藏的超链接使用HTML更改页面,如:

<a href="404.htm" id="myButton" style="display:none;visibility:hidden;"></a>

然后你的按钮可以:

<input type="button" ... onclick="document.getElementById('myButton').click();">

假设任何这样的工作,像这样的隐藏链接是一个丑陋的黑客(第一种可能性并不是更漂亮),但是什么不需要一些丑陋的黑客,当它是关于让MSIE表现得如果它是一个网络浏览器......

答案 2 :(得分:0)

使用下一个代码,您可以针对任何情况解决此问题:

window.location = 'javascript:window.location = "http://www.google.com"';

答案 3 :(得分:0)

我发现在使用回发和非asp标记控件时会调用它两次。将控件从<button>更改为<asp:Button>等,以解决此问题。

答案 4 :(得分:-1)

我想我找到了一个更清洁的问题解决方案。我在回调中将onbeforeunload设置为null,并在退出之前重置它:

...
window.onbeforeunload=confirmExit;

function confirmExit(){
    window.onbeforeunload=null;
    event.returnValue="You have not saved your document yet.";
    window.onbeforeunload=confirmExit;
}