jQuery & Javascript – Capture the Browser or Tab Closed Event

I was working on a WordPress project which i need to clear the PHP session when the browser or browser tab is closed. Although Javascript provides the window.onbeforeunload event but it will be triggered even whenever you leave the website. Finally i got a simple solution from Daniel Melo in StackOverflow. The following code required jQuery and i have included the Google one in the HTML.

In your web root, create the js/check_browser_close.js.

/**
 * This javascript file checks for the brower/browser tab action.
 * It is based on the file menstioned by Daniel Melo.
 * Reference: http://stackoverflow.com/questions/1921941/close-kill-the-session-when-the-browser-or-tab-is-closed
 */
var validNavigation = false;

function endSession() {
  // Browser or broswer tab is closed
  // Do sth here ...
  alert("bye");
}

function wireUpEvents() {
  /*
  * For a list of events that triggers onbeforeunload on IE
  * check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
  */
  window.onbeforeunload = function() {
      if (!validNavigation) {
         endSession();
      }
  }

  // Attach the event keypress to exclude the F5 refresh
  $('document').bind('keypress', function(e) {
    if (e.keyCode == 116){
      validNavigation = true;
    }
  });

  // Attach the event click for all links in the page
  $("a").bind("click", function() {
    validNavigation = true;
  });

  // Attach the event submit for all forms in the page
  $("form").bind("submit", function() {
    validNavigation = true;
  });

  // Attach the event click for all inputs in the page
  $("input[type=submit]").bind("click", function() {
    validNavigation = true;
  });
  
}

// Wire up the events as soon as the DOM tree is ready
$(document).ready(function() {
  wireUpEvents();  
});

 

Also create the following .html in your web root to test the above Javascript file.

<html>
  <head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script type="text/javascript" src="js/check_browser_close.js"></script>
  </head>
  <body>
    <h1>Eureka!</h1>
      <a href="http://www.google.com">Google</a>
      <a href="http://www.yahoo.com">Yahoo</a>
      <a href="http://ykyuen.wordpress.com">Eureka!</a>
  </body>
</html>

 

A alert box will be shown when you closed the browser or the browser tab.

Done =)

Reference:

Update @ 2012-02-19: In Chrome, window.onbeforeunload is required to return a string. please try the following check_browser_close.js.

/**
 * This javascript file checks for the brower/browser tab action.
 * It is based on the file menstioned by Daniel Melo.
 * Reference: http://stackoverflow.com/questions/1921941/close-kill-the-session-when-the-browser-or-tab-is-closed
 */
var validNavigation = false;

function wireUpEvents() {
  /**
   * For a list of events that triggers onbeforeunload on IE
   * check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
   *
   * onbeforeunload for IE and chrome
   * check http://stackoverflow.com/questions/1802930/setting-onbeforeunload-on-body-element-in-chrome-and-ie-using-jquery
   */
  var dont_confirm_leave = 0; //set dont_confirm_leave to 1 when you want the user to be able to leave withou confirmation
  var leave_message = 'You sure you want to leave?'
  function goodbye(e) {
    if (!validNavigation) {
      if (dont_confirm_leave!==1) {
        if(!e) e = window.event;
        //e.cancelBubble is supported by IE - this will kill the bubbling process.
        e.cancelBubble = true;
        e.returnValue = leave_message;
        //e.stopPropagation works in Firefox.
        if (e.stopPropagation) {
          e.stopPropagation();
          e.preventDefault();
        }
        //return works for Chrome and Safari
        return leave_message;
      }
    }
  }
  window.onbeforeunload=goodbye;

  // Attach the event keypress to exclude the F5 refresh
  $('document').bind('keypress', function(e) {
    if (e.keyCode == 116){
      validNavigation = true;
    }
  });

  // Attach the event click for all links in the page
  $("a").bind("click", function() {
    validNavigation = true;
  });

  // Attach the event submit for all forms in the page
  $("form").bind("submit", function() {
    validNavigation = true;
  });

  // Attach the event click for all inputs in the page
  $("input[type=submit]").bind("click", function() {
    validNavigation = true;
  });

}

// Wire up the events as soon as the DOM tree is ready
$(document).ready(function() {
  wireUpEvents();
});

 

Reference: StackOverflow – Setting onbeforeunload on body element in Chrome and IE using jQuery

51 thoughts on “jQuery & Javascript – Capture the Browser or Tab Closed Event

    • I have included the F5 press exception in check_browser_close.js

      ...
        // Attach the event keypress to exclude the F5 refresh
        $('html').bind('keypress', function(e) {
          if (e.keyCode == 116){
            validNavigation = true;
          }
        });
      ...
      

      But this only works for user who press the F5 button, if the user click the refresh button using the mouse, the endSession() will be stilled fired.

      hope this help. =)

  1. I have searched for a working script quite some time, this seems to be the only one that works. Thanks.

  2. This was a real help….Am a pretty newbie,…I just had requirement….

    I want to update a my SQL database and set the status of an online user to ’0′ from ’1′ from the function endsession()….i am stuck here…I tried using an AJAX code here to run a update query but its not working…

    Here is what i’ve done…

    var validNavigation = false;
    
    function endSession() 
    {
      // Browser or broswer tab is closed
      // Do sth here ...
    	alert("You are about to close your page and session");
      
    	var xmlhttp;
    
    	URL = 'localhost/close.php?id=3';
    
    	if (window.XMLHttpRequest)
    	{
    	// code for IE7+, Firefox, Chrome, Opera, Safari
    	xmlhttp=new XMLHttpRequest();
    	}
    	else
    	{
    	// code for IE6, IE5
      	xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    	}
    	
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 &amp;&amp; xmlhttp.status==200)
        {
        document.getElementById("PC").innerHTML=xmlhttp.responseText;
    	
        }
      }
    xmlhttp.open("GET",URL,false);
    xmlhttp.send();
    
      
    }
    
    function wireUpEvents()
    {
      /*
      * For a list of events that triggers onbeforeunload on IE
      * check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
      */
      window.onbeforeunload = function()
      {
          if (!validNavigation)
    	  {
             endSession();
          }
      }
    
      // Attach the event keypress to exclude the F5 refresh
      $('html').bind('keypress', function(e) {
        if (e.keyCode == 116){
          validNavigation = true;
        }
      });
    
      // Attach the event click for all links in the page
      $("a").bind("click", function() {
        validNavigation = true;
      });
    
      // Attach the event submit for all forms in the page
      $("form").bind("submit", function() {
        validNavigation = true;
      });
    
      // Attach the event click for all inputs in the page
      $("input[type=submit]").bind("click", function() {
        validNavigation = true;
      });
    
    }
    
    // Wire up the events as soon as the DOM tree is ready
    $(document).ready(function() {
      wireUpEvents();
    });
    
    • so the update query is inside localhost/close.php? does it work if you just enter this URL in browser?

      If the above checking is positive, i guess there maybe some problem in your ajax request. Maybe you could try implement it in another way as follow.
      Ajax – Simple Ajax GET Request

  3. I have master page and i save data in content page and then do alt+F4 i want to refresh parent page. But it will not calling method endSession() but when i do postback and then do alt+F4 it will call endSession() and my parent page get refereshed.

    function endSession() {
    parent.window.opener.RefreshRiskGrid(); window.close();
    }

    Please give me suggestion.

    Thanks in advance.

  4. Pingback: Browser window close and tab close

      • I have form with image button, link button and Dropdown list, its working fine when click on link or any button, but when select dropdown, this event is called and application signout.

      • In that case you have to add an extra checking when user select the dropdown

          ...
          // Attach the event click for all inputs in the page
          $("input[type=submit]").bind("click", function() {
            validNavigation = true;
          });
        
          // Attach the event when the dropdown option is changed
          $("select#select-id").bind("change", function() {
            validNavigation = true;
          });
          ...
        
  5. HI

    I was wondering , how I can use ur code and disable when someone click on the refresh button in ALL the browsers?

    Is there a solution for that

    Thanks

  6. Hi ykyuen,
    Thanks for this great script! I’m using it to load a survey of why the user is leaving the page without completing a form. It works great for this, but I’m having one problem. If the user tries to submit the form and fails because the form was incomplete, then closes the window, the alert no longer comes up. Please see here:
    http://request4.info/grantham-survey-if-test.html
    Close the page, an alert comes up. Then open the link again. Click Request Information (without filling anything in), and then close the page. Now the alert doesn’t come up. What do I need to do? I’m not changing the value of dont_confirm_leave anywhere… A big thanks in advance for your help!
    –Kyle

    • When the user clicks the Request Information button, the validNavigation is set to TRUE even the form validation is not passed. That’s y the alert box didn’t come out when you close the page.

      How do u implement the form validation?

      One way to resolve ur problem is that whenever the validation is prompted, reset the validNavigation to FALSE.

      • Thanks, that did it! I had to do a settimeout for changing the validNavigation to false though – otherwise the validation function would return false and immediately reset validNavigation to true! Thanks again!

        Also, could you possibly remove my last name from the original post? I’m not sure what I was thinking – I don’t like to use my full name :) Thanks,
        –Kyle

  7. nice solution, but i have a problem to open exit survey after closing page. How can it implemented in chrome as it just return message after closing window. KIndly help on it.

    • I wonder if the following could solve the problem
      1. Change

      $('html').bind('keypress', function(e) {
        if (e.keyCode == 116){
          validNavigation = true;
        }
      });
      

      To

      $('document').bind('keydown', function(e) {
        if (e.keyCode == 116){
          validNavigation = true;
        }
      });
      

      OR

      2. Adding this to the wireUpEvents().

      document.onkeydown = function disableKeys() {
        if( typeof event != 'undefined' ) {
          if(event.keyCode == 116) {
            validNavigation = true;
            event.keyCode = 0;
            //return false; //return false if u want to disable refresh
          }
        }
      };
      

       

      Reference:

      • Thank u very much ykyuen, both solutions worked.
        I’m facing with another silly problem hope you can give some idea about it.
        My website is having some certificate problem, when I log’s in IE gives Information bar giving message “cannot display contents due to certicate errors” when I right click and choose option of “Display blocked content” it refreshes whole page. How can I capture the automatic page refresh of browser in the above javascriptcode?

        Thanks,
        KD

      • It seems that there is no way in Javascript to capture the “Display blocked content refresh”. It should be treated as normal refresh. Maybe you could try to solve the certificate problem.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s