Click here to Skip to main content
Click here to Skip to main content

[JavaScript] 'window.onbeforeunload' fires twice.

By , 12 Oct 2012
 

It is a common practice to handle the 'unsaved data on page' scenario by means of handling 'window.onbeforeunload' event. A typical way of handling this event would be like this.

window.onbeforeunload = handleUnsavedData;

function handleUnsavedData() 
{
  if (pageUpdated) 
  {
    return 'You have unsaved data on the page. Are you sure you want to    navigate away from the page?';
  }
}

This works, but you may have noticed that the 'onbeforeunload' event is getting fired twice, effectively executing the function 'handleUnsavedData' twice!

Well, there is a work around for this. The solution is to disable the event handler. So the code would look like below:

function handleUnsavedData() 
{ 
    if(pageUpdated) 
    { 
        event.returnValue = 'You have unsaved data on the page. ' + 
          'Are you sure you wan to navigate away from the page?'; 
        window.onbeforeunload = null; 
    } 
}

Now this makes sure that the event is not fired twice - only to introduce a new problem!

Imagine that you have chosen not to exit the page when you were warned. Now you are back in your page (without a post-back of course). If you try to navigate away from the page again, will it warn you? Of course not, because you have nullified the event handler. 

Luckily there is a work around for that too :-) 

The idea is to temporarily disable the event handler and then enable it later (within a few milliseconds). The modified code would look like below.

function handleUnsavedData() 
{ 
    if(pageUpdated) 
    { 
        event.returnValue = 'You have unsaved data on the page. ' + 
          'Are you sure you wan to navigate away from the page?'; 
        window.onbeforeunload = null; 
        setTimeout("enableBeforeUnloadHandler()", "100"); 
    } 
} 

function enableBeforeUnloadHandler()  { window.onbeforeunload = confirmExit; }

In this case, the event handler would be reinstated shortly after returning to the page. You may want to play with the '100 ms' a little bit to suit your requirements.

Happy coding!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

James Poulose
Software Developer (Senior)
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
SuggestionSome code suggestionsmemberDaniel Lo Nigro16 Oct '12 - 13:22 
Your setTimeout code should be this:
 
setTimeout(enableBeforeUnloadHandler, 100); 
 
Not this:
 
setTimeout("enableBeforeUnloadHandler()", "100"); 
 
Passing a string as the first parameter is deprecated and not recommended, as it's significantly slower than just passing a function.
 
Also, I believe the global event object doesn't exist in non-IE browsers. So I think your last code snippet should look something like:
 
function handleUnsavedData(e) 
{ 
    if(pageUpdated) 
    { 
        var e = e || window.event;
        e.returnValue = 'You have unsaved data on the page. ' + 
          'Are you sure you want to navigate away from the page?'; 
        window.onbeforeunload = null; 
        window.setTimeout(function() { window.onbeforeunload = handleUnsavedData; }, 100); 
    } 
} 
 
 
(I didn't test if the "returnValue" property works in non-IE browsers)
QuestionAnother idea...memberSpiff Dog12 Oct '12 - 11:25 
Another way you could handle this would be to use a confirm dialog. Something like:
 
var msg = "You have unsaved data on the page. Are you sure you wan to navigate away from the page?";
if (confirm(msg))
{
     window.onbeforeunload = null; 
}
-------------------------
Spiffdog Design
It's ok... he doesn't bite...

AnswerRe: Another idea...memberJames Poulose12 Oct '12 - 11:49 
Spiffdog Design,
 
Thanks for the reply.
 
With the above code
 
1. You will get the confirmation dialog twice.
2. Despite choosing cancel (twice), the page continued navigating to another page.
 
Btw, I am using IE9 (I think i should mention that in the article.)
 
Thanks,
James

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 12 Oct 2012
Article Copyright 2012 by James Poulose
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid