Its tricky business to avoid the browser window from beeing closed. Actually, there is no way to do that, beside returning a non-undefined
value from the onbeforeunload
event, like you described.
There is one possible suggestion I can make, that is creating a synchronized ajax request within the onbeforeunload
event. For instance
window.onbeforeunload = function() {
$.ajax({
url: '/foo',
type: 'GET',
async: false,
timeout: 4000
});
};
In theory, this will block the browser for a maximum of 4 seconds. In reality, browsers will treat this differently. For instance, Firefox (I tested it on 9), will indeed not close the window immediately, but it also does not respect the timeout value there. I guess there is an internal maximum of like 2 seconds before the request is canceled and the window/tab gets closed. However, that should be enough in most cases I guess.
Your other question (how to distinguish between clicking a link), is fairly simple. As described above, onbeforeunload
looks what is getting returned from its event handlers. So lets assume we have a variable which is global for our application, we could do something like
var globalIndicator = true;
// ... lots of code
window.onbeforeunload = function() {
return globalIndicator;
};
At this point, we would always receive a confirmation dialog when the window/tab is about to get closed. If we want to avoid that for any anchor-click, we could patch it like
$( 'a[href^=http]' ).on('click', function() {
globalIndicator = undefined;
});