290

I want to make a confirmation before user leaving the page. If he says ok then it would redirect to new page or cancel to leave. I tried to make it with onunload

<script type="text/javascript">
function con() {
    var answer = confirm("do you want to check our other products")
    if (answer){

        alert("bye");
    }
    else{
        window.location = "http://www.example.com";
    }
}
</script>
</head>

<body onunload="con();">
<h1 style="text-align:center">main page</h1>
</body>
</html>

But it confirm after page already closed? How to do it properly?

It would be even better if someone shows how to do it with jQuery?

Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
kd7
  • 2,931
  • 2
  • 15
  • 4
  • 1
    ha ha ha...Yes,that's quite right..but luckily it not my site...my client asking to do it on his side – kd7 Aug 16 '11 at 15:03
  • 36
    Ya, but I am really happy to see those alerts when I am about to quit an unsaved Gmail page. – Etdashou Nov 05 '12 at 14:57
  • Note, on Firefox 4+ only a default message is displayed instead of your custom message https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload#Notes – baptx Oct 18 '15 at 17:45
  • 5
    Possible duplicate of [Warn user before leaving web page with unsaved changes](http://stackoverflow.com/questions/7317273/warn-user-before-leaving-web-page-with-unsaved-changes) – Wasim A. Jan 24 '16 at 01:57

10 Answers10

403

onunload (or onbeforeunload) cannot redirect the user to another page. This is for security reasons.

If you want to show a prompt before the user leaves the page, use onbeforeunload:

window.onbeforeunload = function(){
  return 'Are you sure you want to leave?';
};

Or with jQuery:

$(window).bind('beforeunload', function(){
  return 'Are you sure you want to leave?';
});

This will just ask the user if they want to leave the page or not, you cannot redirect them if they select to stay on the page. If they select to leave, the browser will go where they told it to go.

You can use onunload to do stuff before the page is unloaded, but you cannot redirect from there (Chrome 14+ blocks alerts inside onunload):

window.onunload = function() {
    alert('Bye.');
}

Or with jQuery:

$(window).unload(function(){
  alert('Bye.');
});
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • That's right. You cannot return false from `onunload`. That was a typo. However, what you are doing is returning a string, not a Boolean. For that you'll have to `confirm()`. – Joseph Silber Aug 16 '11 at 15:07
  • 13
    @Joseph: When you return a string from `onbeforeunload`, the browser puts that string into its own confirmation box. Using `confirm` is useless in `onunload` and `onbeforeunload`, because only the browser can control where it goes, not you. Check out this demo: http://jsfiddle.net/3kvAC/ – gen_Eric Aug 16 '11 at 15:10
  • 2
    @Rocket: Tested it all, and you're absolutely right. Thanks! I guess "you learn new things every day"... – Joseph Silber Aug 16 '11 at 15:15
  • @Joseph: `onbeforeunload` and `onunload` are kinda weird. – gen_Eric Aug 16 '11 at 15:16
  • 1
    This worked really well for me +1 What I did was the following: in the text area, set an onkeyup listener, and set a boolean to true when the user changed the textarea. Then in this method, check that boolean, return "You have unsaved changes" and the browser handles the alert. – eplewis89 May 31 '13 at 16:07
  • so to confirm i cannot have a popup message if they leave the page that has a link in it that they can click? ie a facebook share? – Dan Nov 14 '13 at 04:49
  • @Dan: You can check a variable inside the `onbeforeunload`. Like: `if(!facebook){ return '...'; }`. Then just add an extra handler to the share button to toggle the `facebook` variable. – gen_Eric Nov 14 '13 at 14:27
  • 12
    Just a note, if you want to conditionally display a message in `onbeforeunload`, `return false` will make the browser show "false" in a dialog. You need to `return undefined` if you want to let the window close with no user alert. – Dan Fitch Apr 07 '14 at 19:43
  • 1
    This solution works great. In my case I added a conditional return, depending on if the save button is enabled or not. This lets me know if anything was changed: if ($('#id_save_button').attr('disabled') != 'disabled'){ return 'Are you sure you want to leave without saving?'; } – radtek May 21 '14 at 19:38
  • Kinda off topic.. My IDE complains that the return is inconsistent, wants the return at the bottom of the function. What does JavaScript best practices say? – radtek May 21 '14 at 21:13
  • 1
    @radtek: Usually with `onbeforeunload`, I do `if(abc){return 'you wanna leave?';}`. If you want to try to make the IDE happy, you can try `var ret; if(abc){ ret = 'you wanna leave?'; } return ret;`. – gen_Eric May 22 '14 at 13:41
  • I just tried it in Firefox 45.0.2 and it is not showing the string `"Are you sure you want to leave?"`. Instead, a default message appears: `"This page is asking you to confirm that you want to leave - data you have entered may not be saved"`. Do you know how I can make Firefox display my manual message? – Adam Aug 24 '16 at 10:28
  • 7
    @Adam: Firefox decided to disallow customization of that message. That's part of the browser, so you cannot override that behavior. Other browsers may also be removing the ability to customize the message. See: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#Browser_compatibility – gen_Eric Aug 24 '16 at 13:46
  • 11
    @RocketHazmat Chrome has, too. It now only says: **Do you want to leave this site?** Changes you made may not be saved. –  Jan 25 '17 at 18:47
  • 7
    @programmer5000 It's good because some malicious websites can show some useless warnings (for example "You can't leave without giving your bank information") – Naman Oct 29 '17 at 15:39
41

This code when you also detect form state changed or not.

$('#form').data('serialize',$('#form').serialize()); // On load save form current state

$(window).bind('beforeunload', function(e){
    if($('#form').serialize()!=$('#form').data('serialize'))return true;
    else e=null; // i.e; if form state change show warning box, else don't show it.
});

You can Google JQuery Form Serialize function, this will collect all form inputs and save it in array. I guess this explain is enough :)

Wasim A.
  • 9,660
  • 22
  • 90
  • 120
  • any idea why this would not work ? Could it be overwritten by other js functions/jquery plugins ? I'm running a webrtc app and I would like to "close" some stuff when the client closes the window thus the need to handle the window close. – hey Aug 08 '14 at 04:02
  • 1
    this can be overwritten by any other plugin etc, mostly developer made mistake with selector, if you are doubted about overwritten, put your jquery code before close of

    tag.

    – Wasim A. Aug 09 '14 at 06:37
  • Yes... if you have some JS code that hides or disables input fields after the page has been loaded then when you do the check to compare the hidden\disabled fields won't be serialized. The check will fail of course. ;) There's this workaround: http://stackoverflow.com/a/4748748/114029 – Leniel Maccaferri Oct 28 '14 at 01:36
  • By the way... there's a better way here: http://stackoverflow.com/q/16322042/114029 – Leniel Maccaferri Oct 28 '14 at 02:01
  • This is so smart! Thank You! Also for others, don't forget to execute it after the document is ready! – Riki137 Oct 14 '15 at 09:21
  • 1
    should be noted that this will also rise a warning when pressing the submit button. one could serialize the form again on click of the submit button to prevent that. – Adam Sep 03 '16 at 09:35
  • @Adam I have not yet seen that issue – JSON Nov 15 '19 at 18:47
30

This what I did to show the confirmation message just when I have unsaved data

window.onbeforeunload = function() {
  if (isDirty) {
    return 'There is unsaved data.';
  }
  return undefined;
}

returning undefined will disable the confirmation

Note: returning null will not work with IE

Also you can use undefined to disable the confirmation

window.onbeforeunload = undefined;
David Wolf
  • 1,400
  • 1
  • 9
  • 18
Mina Matta
  • 1,024
  • 14
  • 22
22

This will alert on leaving current page

<script type='text/javascript'>
function goodbye(e) {
    if(!e) e = window.event;
    //e.cancelBubble is supported by IE - this will kill the bubbling process.
    e.cancelBubble = true;
    e.returnValue = 'You sure you want to leave?'; //This is displayed on the dialog

    //e.stopPropagation works in Firefox.
    if (e.stopPropagation) {
        e.stopPropagation();
        e.preventDefault();
    }
}
window.onbeforeunload=goodbye; 

</script>
Ajit Singh
  • 1,132
  • 1
  • 13
  • 24
12

In order to have a popop with Chrome 14+, you need to do the following :

jQuery(window).bind('beforeunload', function(){
    return 'my text';
});

The user will be asked if he want to stay or leave.

David Bélanger
  • 7,400
  • 4
  • 37
  • 55
  • Any idea why this is not working ? I'm using chrome ( latest version) along with a bung of jquery plugins but I don't get any alert when when I close the window. – hey Aug 08 '14 at 04:04
  • @hey Why the down vote ? It's working.... You need to make sure it's outside of the `jQuery(document)` and I suggest to put it right after all your plugins are loaded. Also, this snippet doesn't do any alert... it's only a demo with `return`. – David Bélanger Aug 08 '14 at 13:27
11

You can use the following one-liner to always ask the user before leaving the page.

window.onbeforeunload = s => "";

To ask the user when something on the page has been modified, see this answer.

Community
  • 1
  • 1
spencer.sm
  • 19,173
  • 10
  • 77
  • 88
  • does this also fire if i refresh the page or just exit? – Si8 Jan 12 '17 at 16:20
  • Yes, it will fire on a refresh or exit. – spencer.sm Jan 12 '17 at 17:55
  • Is there anyway to know when it is refresh vs when its first time? – Si8 Jan 13 '17 at 00:00
  • When a user comes to the page first time as oppose to the user refreshing the page. – Si8 Jan 13 '17 at 14:19
  • Oh, no. It won't be fired when a user comes to the page for the first time. Only when closing or changing pages or refreshing. – spencer.sm Jan 13 '17 at 15:53
  • Awesome... Thank you. So the first time I can use another function. – Si8 Jan 13 '17 at 15:54
  • I can't get this function to trigger when the user clicks the back button. I've read around and it seems that it's no longer possible to interfere with the functionality of the back button. Is this correct? – L.Youl Dec 04 '20 at 16:49
8

Most of the solutions here did not work for me so I used the one found here

I also added a variable to allow the confirm box or not

window.hideWarning = false;
window.addEventListener('beforeunload', (event) => {
    if (!hideWarning) {
        event.preventDefault();
        event.returnValue = '';
    }

});
Raj Nandan Sharma
  • 3,694
  • 3
  • 32
  • 42
  • When user refresh the page browser refresh button this time ``Blocked attempt to show a 'beforeunload' confirmation panel for a frame that never had a user gesture since its load.`` this error occur any suggestion – Mayur Vaghasiya Mar 10 '21 at 07:25
5

Normally you want to show this message, when the user has made changes in a form, but they are not saved.

Take this approach to show a message, only when the user has changed something

var form = $('#your-form'),
  original = form.serialize()

form.submit(function(){
  window.onbeforeunload = null
})

window.onbeforeunload = function(){
  if (form.serialize() != original)
    return 'Are you sure you want to leave?'
}
Simon Franzen
  • 2,628
  • 25
  • 34
3
<!DOCTYPE html>
<html>
<body onbeforeunload="return myFunction()">

<p>Close this window, press F5 or click on the link below to invoke the onbeforeunload event.</p>

<a href="https://www.w3schools.com">Click here to go to w3schools.com</a>

<script>
function myFunction() {
    return "Write something clever here...";
}
</script>

</body>
</html>

https://www.w3schools.com/tags/ev_onbeforeunload.asp

Emir Mamashov
  • 1,108
  • 9
  • 14
0

Just a bit more helpful, enable and disable

$(window).on('beforeunload.myPluginName', false); // or use function() instead of false
$(window).off('beforeunload.myPluginName');
l2aelba
  • 21,591
  • 22
  • 102
  • 138