views:

99

answers:

2

I want to show a message whenever you are leaving the page (not an annoying alert, just some html telling you to wait), in thinking about it I'm facing certain difficulties:

  • when the user presses Stop in the browser, cancelling the navigate-away action, I'd like the message to go away.

  • whenever any link is clicked, the message should appear.

  • it shouldn't capture when the clicked link just opens another tab ( ignore _blank target )

that being said, firing the event is pretty simple, with just something like

$(document).unload(function()
{
    // display message
});

the problem being that if the user cancels, the message wouldn't go away.

a possible fix would be:

$(window).unload(function()
{
    // display message

    setTimeout(function()
    {
        // hide message
    },5000);
});

but I wanted to know if there was a cleaner way, that just when the user cancels the navigation (or it fails for any other reason), I can hide the message.

Edit #2:

I just noticed that with the above code, in FF the message isn't displayed until the page is left, at which point if the user presses Stop, he will receive about:blank. If he presses Stop before that, then the message is never displayed. Which is exactly what I wanted.

In internet explorer the message is never displayed, I'm assuming that's because IE handles stuff differently. I wonder what happens in chrome?

+2  A: 

As to the first point:

when the user presses Stop in the browser, cancelling the navigate-away action, I'd like the message to go away.

I had the same question a while back, and the resounding response - also backed by my subsequent research - was that this is impossible. Once you start a request for a new page, it's impossible to reliably "come back" from it programmatically. A timeout may indeed be the only way to go.

The two other points, though, should be relatively straightforward: Walk through every link (e.g. using jQuery), and add a click event that opens the confirmation window, and returns false so that the original href isn't opened. It should also be relatively easy to do this for internal links only (check for the target property, if it's _blank, leave the link alone.)

It may become tough to deal with links that already have click events, though, and other events leading to a different page like form submissions.

Pekka
check my edits!
Nico
A: 

Here is a solution that works in all browsers. It uses the document.readyState attribute which works in all browsers except early versions FireFox (works in version 3.6.8). If the browser supports the readyState attribute it will check if the readyState is load (browser is going to another page) or is complete (or something else indicating that the page is not going anywhere). If the browser does not support the readyState then it will default to your solution.

(function(){
    var hideMessage=document.readyState?function(){
        setTimeout(function(){
            if(document.readyState=='loading'){
                hideMessage();
            }else{
                //hide message
            }
        },500);
    }:function(){
        // hide message
    }
    function displayMessage(){
        // display message
    }
    window.onbeforeunload=function(){
        displayMessage();
        setTimeout(hideMessage,document.readyState?10:5000);
    };
}());
Eric
hmmm... I like this, though IE doesn't ever display the message. I'm guessing $(window).unload functions never fire in IE?
Nico
$(window).unload will fire if you have jQuery also loaded and the page is actually unloading, as in another page is being loaded over this page. I copied $(window).unload from the question, which was the wrong event to use. I have changed the code above and it should be working now.
Eric