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

use*_*765 5 html javascript onbeforeunload internet-explorer-9

我一直在敲打和敲打这件事,但无处可去。

我有一个取消按钮,它执行“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>
Run Code Online (Sandbox Code Playgroud)

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

有什么建议?

谢谢!

Jam*_*ose 5

试试这个,这对我有用。此解决方案最初由 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;
}
Run Code Online (Sandbox Code Playgroud)


Sto*_*law 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();">
...
Run Code Online (Sandbox Code Playgroud)

也许还有另一种可能性,根据这篇文章,问题似乎来自于使用 JS 更改页面,您可以使用隐藏的超链接来使用 HTML 更改页面,例如:

<a href="404.htm" id="myButton" style="display:none;visibility:hidden;"></a>
Run Code Online (Sandbox Code Playgroud)

然后你的按钮可以执行以下操作:

<input type="button" ... onclick="document.getElementById('myButton').click();">
Run Code Online (Sandbox Code Playgroud)

假设其中任何一个都有效,像这样的隐藏链接就是一个丑陋的黑客攻击(无论如何第一种可能性也不是那么漂亮),但是当它让 MSIE 表现得像一个网络浏览器时,不需要一些丑陋的黑客攻击。 ..