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 🙂
Advertisement
Answer
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).