Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript event that runs before page changes

Is there such a thing?

I know that I can hook my function on the click event of all links, but there are other situations where a page is changed, like refresh or when a different script changes the window.location


In the end, I did it by sending a string trough postMessage from the unload event, like this:

$(window).bind('unload', function(e){
  window.parent.postMessage('unloading');
});

in the parent document:

$(window).bind('message', function(e){     
  if(e.originalEvent.data == 'unloading'){
    // ajax stuff here
  }
});

It appears to work. I probably should have mentioned that there's a iframe involved :)

like image 929
Alex Avatar asked Jun 24 '12 11:06

Alex


1 Answers

There's the beforeunload event, which is fired when the page is being torn down (either to follow a link, or if the window is being closed, or refresh, etc.). Example:

window.onbeforeunload = function(event) {
    var s = "You have unsaved changes. Really leave?";

    event = event || window.event;
    if (event) {
        // This is for IE
        event.returnValue = s;
    }

    // This is for all other browsers
    return s;
}

There are, for obvious reasons, very strict limits on what you can do in the handler of the beforeunload event, and as you can see above beforeunload handlers have a different signature than normal event handlers. Basically, your code can't do anything asynchronous, can't open new windows, and can't cancel the event. It can return a string, and if it does, the browser will pop up a window asking whether you really want to leave the page, and including your string in that pop-up.

From your comment on the question:

I need it before so I can fire a ajax request and update some things...

The way to do that here many years after the question was originally asked is with the beacon API. This lets you send a non-blocking asynchronous request to the server without slowing down the process of the browser tearing down your page and navigating to the next:

navigator.sendBeacon("/path/to/notify", optionalData);

It's a send-and-forget, but the browser doesn't cancel it when your page is torn down (like it does a standard asynchronous ajax request). Instead, it allows that request to complete even though your page has been removed.

Back in 2012 when this answer was originally written, you could usually get away with a synchronous ajax call (async: false) provided it didn't take too long. But you can't reliably do that now (and it was never a good idea, it holds up the UI).

like image 67
T.J. Crowder Avatar answered Oct 18 '22 00:10

T.J. Crowder