Zer001
Zer001

Reputation: 619

catching beforeunload confirmation canceled?

I want to do some stuff when user is leaving a page, I add this code

window.onbeforunload = function (e){
   return "You save some unsaved data, Do you want to leave?";
}  

This prompt can notify the user and user can stay on the page or leave. But I want more to know whether he leaves or not, and do thing on his decision. I tried this,

window.onbeforunload = function (e){
   var event = jQuery.Event(e);
   var result = confirm('want to leave?');
   if (result ==  false){
     //do sth.. 
     event.preventDefault();
   }else{
    //do clean up
   }
} 

But it fails!! It always goes away!

Can any body help me doing this?

Upvotes: 5

Views: 12951

Answers (3)

emil.c
emil.c

Reputation: 2018

But I want more to know whether he leaves or not, and do thing on his decision

If you wanna do something when he leaves, you can do it in unload event. For example, as @Erik Bakker mentioned you can send async events in unload event.

However if you wanna find out if user "stayed", in other words cancelled the leaving process, there is a way as well. It's kinda hackish, but it works.

const doSomethingWhenUserStays = function doSomethingWhenUserStays() {
  alert('user stayed!!!');
}


window.addEventListener('beforeunload', function onBeforeUnload(e) {
  setTimeout(doSomethingWhenUserStays, 500);
  
  // Dialog text doesn't really work in Chrome.
  const dialogText = 'A dialog text when leaving the page';
  e.returnValue = dialogText;
  return dialogText;
});

Method doSomethingWhenUserStays will be called every time, but if user leaves the page, he won't see what it performed anyway. It can perform asynchronous stuff, synchronous, it doesn't really matter because it's within setTimeout therefore it's out of the normal flow of onBeforeUnload and won't interfere with it.

If you want to perform it ONLY if user really stays on the page it's slightly harder. You'd have to set a global flag that checks whether user reached unload or not and only then call what's inside doSomethingWhenUserStays. Consider the following example.

let hasUserLeft = false;

const doSomethingWhenUserStays = function doSomethingWhenUserStays() {
  // Perform the following only if user hasn't left the page
  if (!hasUserLeft) {
    alert('user stayed!!!');
  }
}


window.addEventListener('beforeunload', function onBeforeUnload(e) {
  // It won't perform doSomethingWhenUserStays in 500ms right after this is called,
  // but instead, it will perform it in 500ms after you click "Stay" or "Leave".
  // Therefore, there should be some time for `unload` handler to fire and
  // set `hasUserLeft` flag before `doSomethingWhenUserStays` is called.
  setTimeout(doSomethingWhenUserStays, 500);
  
  // Dialog text doesn't really work in Chrome.
  const dialogText = 'A dialog text when leaving the page';
  e.returnValue = dialogText;
  return dialogText;
});


window.addEventListener('unload', function onUnload() {
  hasUserLeft = true;
});

Upvotes: 6

saarthak
saarthak

Reputation: 1014

As far as I have read about this method in different browser forums like MSDN, MozillaDev, etc, this method does not have any callbacks for OK/Cancel. You have this for the confirm dialog but not for this.

This is a security implementation to allow users to have full right about which website they should see. Also, it averts hackers from locking users to their sites.

Upvotes: 3

Erik Bakker
Erik Bakker

Reputation: 4589

The method you use (preventing bubbling of the event) is intentionally not possible, otherwise you could prevent users from leaving your page.

You can achieve something similar to what you want by doing your cleanup onunload, and do the stuff you always want to do onbeforeunload.

Upvotes: 7

Related Questions