IE9 onbeforeunload called twice when window.location changed in button event… minimal reproduction

人走茶凉 提交于 2019-12-22 08:08:26

问题


I've been hammering and hammering at this and just can't get anywhere.

I have a cancel button that does a "window.location = '404.htm';" when clicked. The onbeforeunload handler fires twice, but only if the user clicks "Stay on this page" to the first dialog. A normal navigation (page refresh, going to home page) the onbeforeunload handler only fires once.

I've managed to repro the behavior with a minimal amount of HTML and script:

<!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>

There are lots of hits for "onbeforeunload called twice" but no minimal reproduction and no actual solutions.

Any suggestions?

Thanks!


回答1:


Try this, this worked for me. This solution was originally posted by Amit at http://social.msdn.microsoft.com/Forums/eu/sharepointinfopath/thread/13000cd8-5c50-4260-a0d2-bc404764966d?prof=required

Remember, disabling the onbeforeunload temporarily and enabling it back after a short while is the key.

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;
}



回答2:


As anyways your onbeforeunload is interpreted through JS, you probably can use a boolean flag in a global variable to know whether it's the first time the process started by the event runs. Like:

<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();">
...

Another possibility perhaps, as according to this post the problem seems to come from changing the page using JS, you can use a hidden hyperlink to change the page using HTML, something like:

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

Then your button could do:

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

Assuming any of this works, a hidden link like that is an ugly hack (the first possibility isn't much prettier anyway), but what doesn't require some ugly hacks when it's about having MSIE behave like if it was a web browser...




回答3:


With the next code, you can fix this for any case:

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



回答4:


I found that it is called twice when using postback and non-asp tagged controls. Change controls from <button> to <asp:Button>, etc. to solve this.




回答5:


I think I found a cleaner solution to the problem. I set the onbeforeunload to null inside the callback, and reset it prior to exit:

...
window.onbeforeunload=confirmExit;

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


来源:https://stackoverflow.com/questions/9967934/ie9-onbeforeunload-called-twice-when-window-location-changed-in-button-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!