Today I wanted to implement something that would prevent me from accidentally closing the browser window while I was doing stuff in my webapp. I’m no javascript expert, so I checked some newsgroups and found more and more complex solutions the longer the threads were.

Here’s what works for me:

  
<script type="text/javascript">
  window.onbeforeunload = function(){
    return "Did you save your stuff?"
  }
</script>

I have no idea why this behaves as it does, it must be one of those “very interesting ideas” Frank mentioned about javascript.

What it does is this: When the user presses the browser’s “x” to close the window, this dialog box is shown:

confirm dialog box

If the user presses Cancel, the box disappears and the browser window remains open, and if she presses Okay, the browser window closes (who’d have guessed). So far, so good. Unfortunately the message is displayed even if the user clicks on a link or submits a form (to do something within the webapp) .

So how do I fix this? The newsgroups said that I could add a condition to check if I really want to warn the user about closing, like this:

  
<script type="text/javascript">
  var hook=true;
  window.onbeforeunload = function() {
    if (hook) { 
      return "Did you save your stuff?" 
    }
    // no return value obviously means no dialog box. 
  }
  function unhook() {
     hook=false;
  }
</script>

The default is to use the hook, and I can use the unhook() function to disable the hook. How does this help? How do I know when I want the hook disabled? Frank knew the solution, and it’s really very simple: I want to disable the hook whenever the user clicks on one of my own links or buttons within the webapp. This can be done by adding an onClick event to each link or button like this:

<a href="..." onClick="unhook()">Some link within my app</a>

At first it looks a bit cumbersome to change all the links and buttons, but in a webapp, most of the links will be written by some application code anyway so it’s not much trouble to change them all at once.

It’s a bit strange because what I’m doing here is programming some general behaviour (the hook) and then exclude all the common use-cases (internal links, by calling unhook()) because I can’t make javascript react to the few exceptions (browser close button) directly.

The final page looks something like this:

<html>
  <head>
    <script type="text/javascript">
      var hook = true;
      window.onbeforeunload = function() {
        if (hook) { 
          return "Did you save your stuff?" 
        }
      }
      function unhook() { 
        hook=false; 
      }
    </script>
  </head>
  <body>
    <!-- this will ask for confirmation: -->
    <a href="http://google.com">external link</a>

    <!-- this will go without asking: -->
    <a href="anotherPage.html" onClick="unhook()">internal link, un-hooked</a>
  </body>
</html>

Closing or re-loading the window will display the confirm box, too.

Use the following links to check that it works:
Don’t leave for Google before you leave a comment.
You shouldn’t be able to close this page without warning, either.

There’s one small problem left: if you click on the “leave a comment” link, the page will not be re-loaded because it’s just a page-internal link, and after that, the hook variable will be false and you won’t be asked for confirmation if you click on the google link again. But thankfully I don’t have these page-internal links in my webapp…

Addendum: Claus Augusti directed my attention to two official documentation sites about the onbeforeunload event. Thanks you! The documentation in the Mozilla Developer Center explains that one should not just return a string, but should assign a value to the returnValue property of the onbeforeunload event (browser-dependent), like this:

window.onbeforeunload = function (e) {
  var e = e || window.event;
  if (e) {   // For IE and Firefox
    e.returnValue = 'Any string';
  }
  return 'Any string';   // For Safari
};

This is contradictory to the example given in Microsoft’s documentation (returning a string is sufficient), and contrary to my experience with Firefox, but at least it helps to understand why this works at all.


32 Responses to “Javascript “close hook” for browser window”

  1. 1

    Can we customize the message displayed on the popup box?
    I just want to display my required message without the inbuilt ones (Are you sure you want to navigate away from this page? Press OK to continue or Cancel to stay on the current page).

    suhail (April 7th, 2009 at 12:37)
  2. 2

    Hi Suhail,
    thanks for your comment! It is not possible to remove or change the inbuilt message. See also the documentation on msdn.microsoft.com (section “Remarks”).

    schlumpf (April 8th, 2009 at 05:11)
  3. 3

    Suhail

    I using similar code to display a message box when the user navigates away from the page without saving it.

    But I get javascript error : “unspecified error” when cancel button is clicked in the message box.

    Below is my code,

    var needToConfirm = true;
    window.onbeforeunload = confirmExit;
    function confirmExit()
    {
    if(needToConfirm)
    return ‘You have made changes to the fields. Without clicking the Save button, your changes will be lost.’;

    }

    Thanks in advance, VJ.

    VJ (July 2nd, 2009 at 12:55)
  4. 4

    Schlumpf

    The last post is for you, I’ve addressed it wrongly.

    Any help on that is much appreciated.

    Thanks, VJ

    VJ (July 2nd, 2009 at 12:58)
  5. 5

    Hi VJ,
    thanks for your comment! Your code works fine in my browser (Firefox 3.0.8 on Gentoo Linux). What browser are you using?

    One thing you might want to try is use the event.returnValue as described in the addendum to the original post. Or you could install FireBug, the javascript debugging plugin for Firefox, and try to find out what’s going on (if you are using Firefox at all). Hope this helps!

    schlumpf (July 2nd, 2009 at 19:26)
  6. 6

    Hello,

    I appreciate the way you have opted for displaying warning message. But I am not satisfied with this code as it does not function properly. Browser close message should only be called when someone closes or refreshes not by clicking links. Links where you have mentioned onClick=”unhook()” works fine but after clicking such a link if you close or refresh the browser the Warning message does not appear, have you really tested it? If not then check this scenario…I would really thank you if you can resolve this issue. Even I had written the same, here it is:

    // warning message javascript
    var needToConfirm = true;

    window.onbeforeunload = confirmExit;
    function confirmExit()
    {
    if (needToConfirm)
    return “”;
    }

    and then for links: Test

    But once you click the link the state remains in FALSE and that’s why the Warning message does not show. Let me know if you could fix this?

    Cheers,
    Ayush

    Ayusman Mohanty (November 3rd, 2009 at 11:20)
  7. 7

    Hi Ayusman,
    thanks for your comment! I’m not sure if wordpress didn’t scramble the test link in your comment – it was just empty <a>Test</a>. If this is what you intended, then I think I know why the unhook-Thing doesn’t work properly in your case. Normally, when you click a link, the browser reloads the page, which automatically resets all javascript variables. In your case, no reload is triggered and all variables remain unchanged – the needToConfirm variable will still be false.

    schlumpf (November 3rd, 2009 at 12:15)
  8. 8

    Hey,

    Thanks for your reply on this. What I wanted to tell you is: in an anchor tag to avoid the onClick function triggering the prompt box you are setting the onClick as false, right. So what’s happening once you click this link and then when you try refreshing or closing the browser the Warning Message will not appear because the onClick is set as false…

    Hope you got me now else I will again explain you…

    Ayusman Mohanty (November 3rd, 2009 at 12:53)
  9. 9

    Did you get to understand the scenario which I had been trying to explain you?

    Ayusman Mohanty (November 3rd, 2009 at 13:02)
  10. 10

    Okay, looks like you are confused…See for example I have a website which uses JSF and links are defined in h:commandlink tag. Now if I want to make 1000 links as onclick my warning message function as false then I would not prefer to go to each link and add onclick false so in this case what will be the common fix?

    Ayusman Mohanty (November 3rd, 2009 at 13:23)
  11. 11

    Hi Ayusman,
    you can’t catch only the unexpected closing events (like refresh, close browser) — since they’re unexpected you don’t know what they will be before they appear. Therefore you need to catch ALL closing events and explicitly exclude those events you know about (i.e. your own links and buttons) by placing the . If you’re using JSF to create your website, it should be easy to add some code that makes the onclick appear automatically at each link (use a template or something).

    Concerning your first question, can you post a whole html page with which I can reproduce the problem? You’ll need to html-escape all < and > signs like this: &lt; and &gt; else it will be scrambled by the wordpress software.

    schlumpf (November 3rd, 2009 at 15:28)
  12. 12

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
    <html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Untitled Document</title>
    <script type="text/javascript">
    var needToConfirm = true;

    window.onbeforeunload = confirmExit;
    function confirmExit()
    {
    if (needToConfirm)
    return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
    }
    </script>
    </head>
    <body>
    <a href="http://www.google.com">Test</a&gt;
    </body>
    </html>

    Ayusman Mohanty (November 4th, 2009 at 05:44)
  13. 13

    hello

    The above script is working fine while closing browser, but if i press refresh button it alerts the pop up message. I need the pop up only at the time of closing the browser not refresh or navigation through the pages.

    Thanks in advance.

    Kamatchi (November 12th, 2009 at 08:06)
  14. 14

    Hi Kamatchi,
    thanks for your comment. As far as I know, it’s not possible to distinguish between refresh and close events. But I’m not really an expert on this… I just copied the code from somewhere else.

    schlumpf (November 16th, 2009 at 17:24)
  15. 15

    Hi Ayusman,
    sorry for the delay in replying to your last comment. I copied your code into a html file and opened it in my browser. It works as expected.

    I added some code:
    onclick="needToConfirm=false" to the google link, and then it deactivates the popup message as expected.

    If you right-click the link and say “open in new window”, it does set the needToConfirm to false, too (similar effect when you add target="blank" to the link which opens the link in a new window) , but the main window is NOT relaoded and the needToConfirm remains false, and when you then refresh or close the main window, the warning message is not shown. That’s a problem indeed, for which I have no solution. Perhaps there’s some javascript action which can be executed AFTER a link was clicked, then we could use that to set needToConfirm=”true” again?

    schlumpf (November 16th, 2009 at 17:34)
  16. 16

    confirmClose=true;
    function closeSession() {
    if (confirmClose) {
    if (confirm(‘Are you want to close the page?’)) {
    $.ajax({
    asyn: false,
    url: ‘/BrowserClose.aspx’,
    type: ‘Post’,
    data: {},
    contentType: “application/json; charset=utf-8″,
    dataType: “json”,
    success: function (msg) {
    //alert(‘sucess’);
    },
    error: function (xhr, ajaxOptions, thrownError) {
    //alert(xhr.status);
    //alert(xhr.statusText);
    //alert(thrownError);
    }
    });
    } else { return ; }
    }
    }

    window.onbeforeunload = closeSession;

    i use ajax so pls give me soution

    Bharani (December 1st, 2011 at 16:17)
  17. 17

    Sorry mate, I don’t handle “pls give me soution” requests.

    Frank Spychalski (December 1st, 2011 at 17:17)
  18. 18

    well, *I* do answer them, if you, dear Bharani, tell me what the problem is? Is there any way I can reproduce it in my own browser/webserver?

    schlumpf (December 1st, 2011 at 19:00)
  19. 19

    if i using this code if user click browser close means ajax called and browser also closed pls give solution or sample page to how to use ajax when return value find to call ajax

    function closeSession() {
    //alert(confirmClose);
    if (confirmClose) {
    //if (confirm(‘Are you want to close the page?’)) {
    ////alert(‘/Login.aspx/hostoruser_Logout’);
    //} else { return; }
    return test();
    }
    }

    var sucess = false;
    var ajaxSubmit = false;

    function test() {
    if (sucess == true)
    return “Are you want to close the page?”;

    if (ajaxSubmit == false) {
    ajaxSubmit = true;
    $.ajax({
    asyn: false,
    url: ‘/BrowserClose.aspx’,
    type: ‘Post’,
    data: {},
    contentType: “application/json; charset=utf-8″,
    dataType: “json”,
    success: function (msg) {
    //alert(‘sucess’);
    sucess = true;

    },
    error: function (xhr, ajaxOptions, thrownError) {
    //alert(xhr.status);
    //alert(xhr.statusText);
    //alert(thrownError);
    }
    });
    }

    setTimeout(test(), 200);
    }

    window.onbeforeunload = closeSession;

    this is code right now i use but it says “Too much of recursion”

    Bharani (December 2nd, 2011 at 07:49)
  20. 20

    function closeSession(){
    if(confirmclose) {
    return test(); /// i want to find retrun value and tehn use ajax function to update isActive field in user table
    }
    }

    if the possible to find retrun value to call the ajax function

    Bharani (December 2nd, 2011 at 08:08)
  21. 21

    i need all these happen only when browser close [x] is clicked

    Bharani (December 2nd, 2011 at 08:15)
  22. 22

    var confirmClose = true;
    var keyCode = 0;

    function closeSession(evt){
    if(confirmClose){
    return ‘Bharani’; i want to find retrun value and tehn use ajax function to update isActive field in user table
    }
    }

    window.onbeforeunload = closeSession;

    <!– doSomething(event);–>

    test

    Google

    i need all these happen only when browser close [x] is clicked

    Bharani (December 2nd, 2011 at 10:10)
  23. 23

    var confirmclose = true;
    var sucess = false;
    var ajaxSubmit = false;

    function closeSession(){
    if(confirmclose) {
    return “close”; i want to find retrun value and tehn use ajax function to update isActive field in user table
    }
    }

    window.onbeforeunload = closeSession;

    test

    fewfwef

    i need all these happen only when browser close [x] is clicked

    Bharani (December 2nd, 2011 at 15:09)
  24. 24

    <!–

    var confirmclose = true;
    var sucess = false;
    var ajaxSubmit = false;

    function closeSession(){
    if(confirmclose) {
    return “close”;
    }
    }

    window.onbeforeunload = closeSession;

    test

    Google
    fewfwef

    –>

    Bharani (December 2nd, 2011 at 15:10)
  25. 25

    Hi Bharani,

    I don’t think you can find out the return value. Showing the popup message is the last thing that happens in the onbeforeunload event/method, and after that, javascript is not running any more, so you can’t do anything in your script to react to the user’s input. I’m sorry. You could do a workaround by storing the information that the user tried to close the window BEFORE showing the message, like this:

    <html><body>
    <script type="text/javascript">
    triedToClose=false;
    window.onbeforeunload = function() {
    triedToClose = true
    return "Did you save your stuff?"
    }

    function checkClosing() {
    if (triedToClose) {
    alert("user tried to close the window but changed his mind")
    } else {
    alert("user didn't try to close the window")
    }
    }
    </script>

    <pre>
    To use:

    1. click on the test link, see what happens.
    2. try to close the window (browser (x)) - then select "stay on page"
    3. click on the test link again - see that the message changed.

    <a href="#" onclick="checkClosing()" rel="nofollow">Some test link</a>
    </pre></body></html>

    Please note that you can only evaluate the result if the user performs some action on your page, such as clicking on the test link. You would need to add the checkClosing() call to all your links and buttons and could even add it to the onbeforeunload function itself. not very elegant but the best I can do.

    Hope this helps!

    schlumpf (December 2nd, 2011 at 21:04)
  26. 26

    Hi schlumpf ,

    I was done task thanks for your help. And one more help if possible to handle the browser close,minimize etc in javascript or jquery if possible means i need how to handle entire browser options and properties,event

    Note: All browsers to handle

    bharani (December 3rd, 2011 at 11:36)
  27. 27

    #Hi Bharani,

    #I don’t think you can find out the return value. Showing the popup message is the last thing that happens in the onbeforeunload event/method, and after that, #javascript is not running any more, so you can’t do anything in your script to react to the user’s input. I’m sorry. You could do a workaround by storing the #information that the user tried to close the window BEFORE showing the message, like this:

    ok but the return value is sent to where? i need that one so if we find means we can handle the allthings of browser is possible means we are done.
    [email protected]

    bharani (December 3rd, 2011 at 11:39)
  28. 28

    Hi Bharani,
    the return value is sent to nowhere. Or if it is, I don’t know. I’m not a javascript expert, just stumbled over this solution on the web and wrote it down here. Sorry, can’t help you any further with that.

    schlumpf (December 5th, 2011 at 12:57)
  29. 29

    It helps a lot, thank you.

    I could use this routine to check if the user has left out something before closing the window. Really thank you!

    Charles (July 31st, 2012 at 18:55)
  30. 30

    hi confirmation code is working fine,but i need to display the confirmation dailogue only on closing the browser window but not on cliking the refresh button of the window ,can you plz tell me how to do this?

    Thanks in advance

    vidya (March 26th, 2013 at 05:58)
  31. 31

    Hi Vidya, thanks for your comment. It is not possible to distinguish between different browser close/reload events.

    schlumpf (April 21st, 2013 at 10:19)
  32. 32

    Thanks Vidya,
    its working

    Rahul (July 17th, 2013 at 12:30)

Any comments? Or questions? Just leave a Reply: