views:

2184

answers:

3

I've posted this here, but thought it might deserve a question on its own.

What I'm trying to do is show a dialog box that asks the user if he/she wants to leave the page if there are unsaved changes. That all works fine. But the problem is described below:

Has anyone come across the problem where Internet Explorer fires the onbeforeunload event twice? While Googling around, I found it has something to do with the fact that for (among others) an ASP.NET linkbutton the HTML code is <a href="javascript: __doPostBack... Apparently, when IE encouters a link that doesn't have a href="#", it fires the onbeforeunload event. Then, when you confirm the javascript dialog box we're showing, the page will do the 'real' unload to navigate to the other page, and raise the onbeforeunload event a second time.

A solution offered on the internet is to set a boolean variable and check on it before showing the dialog. So the second time, it wouldn't be shown. That's all well, but when the user cancels, the variable will still be set. So the next time the user wants to leave the page, the dialog won't be shown anymore.

Hope this is a little clear, and I hope someone has found a way around this?

+1  A: 

I haven't encountered this, but surely you could set the flag variable to be equal to the result of the dialog? If the user cancels the flag will therefore remain false.

var bFlag = window.confirm('Do you want to leave this page?');
annakata
+4  A: 

Yes, but you want the result of the dialog box to be used by the browser. So you might think using 'return bFlag' would do the trick (or event.returnValue = bFlag), but that gives you a second dialog box. I've found a way around, thanks to http://www.codeproject.com/KB/aspnet/EWSWebPt2.aspx'>this page. It's quite simple actually:

var onBeforeUnloadFired = false;

Use this global variable here:

if (!onBeforeUnloadFired) {
    onBeforeUnloadFired = true;
    event.returnValue = "You'll lose changes!";
}
window.setTimeout("ResetOnBeforeUnloadFired()", 1000);

And then implement that function:

function ResetOnBeforeUnloadFired() {
    onBeforeUnloadFired = false;
}

So, in effect, use the flag, but reset it if the user clicks cancel. Not entirely what I would like, but haven't found anything better.

Peter
I think you're taking my answer to literally. I meant you want to store the confirm value in a flag you use to check before you show the dialog. I guess you got there either way :)
annakata
A: 

IE supports an event on the document object called onstop. This event fires after the onbeforeunload event, but before the onunload event. This isn't exactly pertinent to your two dialogs question, but its still relevant to other people that might stumble on this thread ( as I did ).

The problem I was having, was that I needed to display a loading message upon the onbeforeunload event firing. This is all fine until the page has some sort of confirm dialog on it. The onbeforeunload event fires even if the user cancel's and remains on the page. The easiest thing for me to do was to move my "loading" display logic into a handler for document.onstop. On top of this, you have to check the readyState property of the document object, which is another IE-only field. If its "loading", it means the user is actually leaving the page. If its "complete", it means the user is staying.

If you are fine with just using IE, then you might be interested in the following.

document.onstop = function() 
{
    try
    {
     if( document.readyState != "complete" )
     {
      showLoadingDiv();
     }
    }
    catch( error )
    {
     handleError( error );
    }
}