views:

390

answers:

1

I'm capturing the window.onbeforeunload event using the following code:

window.onbeforeunload = function (evt) 
{

 if(checkIsDirty())
        { 
            var message = 'If you continue your changes will not be saved.'; 
            if (typeof evt == 'undefined') 
            {   
                //IE 
                evt = window.event; 
            } 
            if (evt) 
            { 
                evt.returnValue = message; 
            }
            else
            {
                return message; 
            }
        }

}

When I click 'Cancel' in the resulting confirmation, I get the error "Unknown Exception" and the following is highlighted by the debugger:

onclick="location.href='/<WhicheverPageYouRequested>.aspx';

If I click OK, the page changes perfectly. Why am I getting this error, and how can I fix it?

+4  A: 

Yes, it's a known IE behaviour. When you try to navigate from JavaScript (using location, location.href, location.replace, document.location, history, even roundabout methods like link.click or form.submit), a beforeunload Cancel will raise an exception. The test case is as simple as:

window.onbeforeunload= function() { return '?'; }
location.href= 'http://www.example.com/';

This might even be deliberate, to let the script know the navigation attempt failed, except that the error name is so completely useless. (I get “Unspecified Error”.)

The traditional solution is just to catch it:

try {
    location.href= '...';
} catch(e) {}

I'm always suspicious of that though as catching all exceptions is generally bad news (but IE doesn't allow you to only catch this exception... short of checking for the exact stringTo, which is horribly fragile.

Another approach is to move the onbeforeunload work to the calling code so that the real onbeforeunload never happens and there is no exception:

function navigate(url) {
    if (window.onbeforeunload) {
        if (confirm(window.onbeforeunload()+' Press OK to continue, or Cancel to stay on the current page.')
            window.onbeforeunload= '';
        else
            return;
    }
    location.href= url;
}

However either solution may be beyond your grasp if, as seems likely, it is whatever framework you are using that is inserting the code, rather than it being something you've written yourself.

onclick="location.href='/<WhicheverPageYouRequested>.aspx'";

what sort of control is this? It looks suspicious in itself to be honest: surely something you click on to go to another page should be marked up as a simple link, and not a JavaScript-onclick element (these go wrong in many ways). If it were a simple non-JavaScript link you wouldn't have to worry about the IE error.

Incidentally, your beforeunload function will probably fail on non-IE browsers (returnValue is an IE-only thing). It also seems a bit over-complicated... what's wrong with:

window.onbeforeunload= function() {
    if(checkIsDirty())
        return 'If you continue your changes will not be saved.';
}
bobince