Thursday, October 11, 2012

[JavaScript] 'window.onbeforeunload' fires twice.

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 ofcourse). 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 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, 

James Poulose

No comments:

Post a Comment