Browsers continue to perform Javascript after "PageUnload" & new "PageLoad" - javascript

We have the following AJAX throttler. This was implemented to be able to perform many (20+) ajax requests for one page without the remainder timing out just because the first X requests took a total of 60 seconds.
RequestThrottler: {
maximumConcurrentRequests: 3, //default to 3
requestQueue: new Array(),
numberOfRequestCurrentlyProcessing: 0,
addRequestToQueue: function (currentRequest) {
var self = this;
self.requestQueue.push(currentRequest);
if (self.numberOfRequestCurrentlyProcessing < self.maximumConcurrentRequests) { self.sendNextRequest(); }
},
sendNextRequest: function () {
var self = this;
if (self.numberOfRequestCurrentlyProcessing >= self.maximumConcurrentRequests) { return; }
if (self.requestQueue.length === 0) { return; }
var currentRequest = self.requestQueue.pop();
self.numberOfRequestCurrentlyProcessing++;
AJAX.SendAjaxRequest(currentRequest.url, currentRequest.httpMethod,
function(data){
self.numberOfRequestCurrentlyProcessing--;
currentRequest.onSuccessCallback(data);
self.sendNextRequest();
},
function(){
self.numberOfRequestCurrentlyProcessing--;
currentRequest.onErrorCallback();
self.sendNextRequest();
});
},
sendUpdateRequest: function (currentRequest) {
var self = this;
self.addRequestToQueue(currentRequest);
}
}
However, because these requests are sitting in a Javascript queue, when the user attempts to load a new page, the developer tools show the responses in the NET area of the new page. Our app has a check in place for privacy reasons to not allow this kind of behavior. Is this normal for browsers, or is it some sort of bug, or am I doing something wrong?

A clean solution would be to listen to the window.onbeforeunload event to abort any ajax requests that have yet to receive a response.
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
Abort Ajax requests using jQuery
jQuery: Automatically abort AjaxRequests on Page Unload?
The beforeunload event should be used rather than unload for the following reasons:
1) The beforeunload event is more reliable than unload event:
The exact handling of the unload event has varied from version to
version of browsers. For example, some versions of Firefox trigger the
event when a link is followed, but not when the window is closed. In
practical usage, behavior should be tested on all supported browsers,
and contrasted with the proprietary beforeunload event.
source:
http://api.jquery.com/unload/
jquery: unload or beforeunload?
2) The beforeunload event can be cancelled whereas the unload event cannot be cancelled. This would give you the flexibility if you wanted to prompt the user when beforeunload event takes place. The confirmation will ask the user if they would like to continue to navigate to the other page or if they would like to cancel because not all ajax requests have completed.
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
(e || window.event).returnValue = confirmationMessage; // Gecko and Trident
return confirmationMessage; // Gecko and WebKit
});
sources:
https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload
https://developer.mozilla.org/en-US/docs/Web/Events/unload

Related

Jquery browser close event only need [duplicate]

Is there any cross-browser JavaScript/jQuery code to detect if the browser or a browser tab is being closed, but not due to a link being clicked?
If I get you correctly, you want to know when a tab/window is effectively closed. Well, AFAIK the only way in JavaScript to detect that is to use either onunload or onbeforeunload events.
Unfortunately (or fortunately?), those events are also fired when you leave a site over a link or your browsers back button. So this is the best answer I can give, I don't think you can natively detect a pure close in JavaScript. Correct me if I'm wrong here.
From MDN Documentation
For some reasons, Webkit-based browsers don't follow the spec for the dialog box. An almost cross-working example would be close from the below example.
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
This example for handling all browsers.
Simple Solution
window.onbeforeunload = function () {
return "Do you really want to close?";
};
<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">
var myclose = false;
function ConfirmClose()
{
if (event.clientY < 0)
{
event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
setTimeout('myclose=false',10);
myclose=true;
}
}
function HandleOnClose()
{
if (myclose==true)
{
//the url of your logout page which invalidate session on logout
location.replace('/contextpath/j_spring_security_logout') ;
}
}
//This is working in IE7, if you are closing tab or browser with only one tab
For similar tasks, you can use sessionStorage to store data locally until the browser tab is closed.
The sessionStorage object stores data for only one session (the data is deleted when the browser tab is closed).(W3Schools)
This is my pen.
<div id="Notice">
<span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
$("#Notice").click(function() {
//set sessionStorage on click
sessionStorage.setItem("dismissNotice", "Hello");
$("#Notice").remove();
});
if (sessionStorage.getItem("dismissNotice"))
//When sessionStorage is set Do stuff...
$("#Notice").remove();
</script>
I needed to automatically log the user out when the browser or tab closes, but not when the user navigates to other links. I also did not want a confirmation prompt shown when that happens. After struggling with this for a while, especially with IE and Edge, here's what I ended doing (checked working with IE 11, Edge, Chrome, and Firefox) after basing off the approach by this answer.
First, start a countdown timer on the server in the beforeunload event handler in JS. The ajax calls need to be synchronous for IE and Edge to work properly. You also need to use return; to prevent the confirmation dialog from showing like this:
window.addEventListener("beforeunload", function (e) {
$.ajax({
type: "POST",
url: startTimerUrl,
async: false
});
return;
});
Starting the timer sets the cancelLogout flag to false. If the user refreshes the page or navigates to another internal link, the cancelLogout flag on the server is set to true. Once the timer event elapses, it checks the cancelLogout flag to see if the logout event has been cancelled. If the timer has been cancelled, then it would stop the timer. If the browser or tab was closed, then the cancelLogout flag would remain false and the event handler would log the user out.
Implementation note: I'm using ASP.NET MVC 5 and I'm cancelling logout in an overridden Controller.OnActionExecuted() method.
I found a way, that works on all of my browsers.
Tested on following versions:
Firefox 57, Internet Explorer 11, Edge 41, one of the latested Chrome (it won't show my version)
Note: onbeforeunload fires if you leave the page in any way possible (refresh, close browser, redirect, link, submit..). If you only want it to happen on browser close, simply bind the event handlers.
$(document).ready(function(){
var validNavigation = false;
// Attach the event keypress to exclude the F5 refresh (includes normal 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;
});
window.onbeforeunload = function() {
if (!validNavigation) {
// -------> code comes here
}
};
});
There is no event, but there is a property window.closed which is supported in all major browsers as of the time of this writing. Thus if you really needed to know you could poll the window to check that property.
if(myWindow.closed){do things}
Note:
Polling anything is generally not the best solution. The window.onbeforeunload event should be used if possible, the only caveat being that it also fires if you navigate away.
Sorry, I was not able to add a comment to one of existing answers, but in case you wanted to implement a kind of warning dialog, I just wanted to mention that any event handler function has an argument - event. In your case you can call event.preventDefault() to disallow leaving the page automatically, then issue your own dialog. I consider this a way better option than using standard ugly and insecure alert(). I personally implemented my own set of dialog boxes based on kendoWindow object (Telerik's Kendo UI, which is almost fully open-sourced, except of kendoGrid and kendoEditor). You can also use dialog boxes from jQuery UI. Please note though, that such things are asynchronous, and you will need to bind a handler to onclick event of every button, but this is all quite easy to implement.
However, I do agree that the lack of the real close event is terrible: if you, for instance, want to reset your session state at the back-end only on case of the real close, it's a problem.
$(window).unload( function () { alert("Bye now!"); } );
onunload is the answer for Chrome. According to caniuse its crossbrowser. But not all browsers react the same.
window.onunload = function(){
alert("The window is closing now!");
}
developer.mozilla.org
These events fire when the window is unloading its content and resources.
For Chrome:
onunload executes only on page close. It doesn't execute even on page refresh and on navigating to a different page.
For Firefox v86.0:
It wouldn't execute at all. Page refresh, navigating away, closing browser tab, closing browser, nothing.
Since no one has mentioned it yet (8+ years later): A WebSocket can be another effective way to detect a closed tab. As long as the tab is open and pointed at the host, the client is able to maintain an active WebSocket connection to the host.
Caveat: Please note that this solution is really only viable for a project if a WebSocket doesn't require any additional significant overhead from what you are already doing.
Within a sensible timeout period (e.g. 2 minutes), the server side can determine that the client has gone away after the WebSocket has disconnected and perform whatever action is desired such as removing uploaded temp files. (In my extremely specialized use-case, my goal was to terminate a localhost app server three seconds after the WebSocket connection drops and all CGI/FastCGI activity terminates - any other keep-alive connections don't affect me.)
I had problems getting the onunload event handler to work properly with beacons (as recommended by this answer). Closing the tab did not appear to trigger the beacon and open tabs triggered it in ways that could potentially cause problems. A WebSocket solved the problem I was running into more cleanly because the connection closes roughly around the same time that the tab closes and switching pages within the application simply opens a new WebSocket connection well within the delay window.
It can be used to alert the user if some data is unsaved or something like that. This method works when the tab is closed or when the browser is closed, or webpage refresh.
It won't work unless the user has not interacted with the webpage, this is a mechanism to fight malicious websites..... there will be no popup unless you atleast make a click or touch on the website window.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<textarea placeholder = "Write...."></textarea>
</form>
<script type="text/javascript">
window.addEventListener('beforeunload', function (e) {
e.returnValue = '';
});
</script>
</body>
</html>
window.onbeforeunload = function() {
console.log('event');
return false; //here also can be string, that will be shown to the user
}
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
e = e || window.event;
var localStorageTime = localStorage.getItem('storagetime')
if(localStorageTime!=null && localStorageTime!=undefined){
var currentTime = new Date().getTime(),
timeDifference = currentTime - localStorageTime;
if(timeDifference<25){//Browser Closed
localStorage.removeItem('storagetime');
}else{//Browser Tab Closed
localStorage.setItem('storagetime',new Date().getTime());
}
}else{
localStorage.setItem('storagetime',new Date().getTime());
}
});
JSFiddle Link
Hi all, I was able to achieve 'Detect Browser and Tab Close Event' clicks by using browser local storage and timestamp. Hope all of you will get solved your problems by using this solution.
After my initial research i found that when we close a browser, the browser will close all the tabs one by one to completely close the browser. Hence, i observed that there will be very little time delay between closing the tabs. So I taken this time delay as my main validation point and able to achieve the browser and tab close event detection.
I tested it on Chrome Browser Version 76.0.3809.132 and found working
:) Vote Up if you found my answer helpful....
I have tried all above solutions, none of them really worked for me, specially because there are some Telerik components in my project which have 'Close' button for popup windows, and it calls 'beforeunload' event. Also, button selector does not work properly when you have Telerik grid in your page (I mean buttons inside the grid) So, I couldn't use any of above suggestions. Finally this is the solution worked for me.
I have added an onUnload event on the body tag of _Layout.cshtml. Something like this:
<body onUnload="LogOff()">
and then add the LogOff function to redirect to Account/LogOff which is a built-in method in Asp.Net MVC. Now, when I close the browser or tab, it redirect to LogOff method and user have to login when returns. I have tested it in both Chrome & Firefox. And it works!
function LogOff() {
$.ajax({
url: "/Account/LogOff",
success: function (result) {
}
});
}
window.onbeforeunload = function ()
{
if (isProcess > 0)
{
return true;
}
else
{
//do something
}
};
This function show a confirmation dialog box if you close window or refresh page during any process in browser.This function work in all browsers.You have to set isProcess var in your ajax process.
It is possible to check it with the help of window.closed in an event handler on 'unload' event like this, but timeout usage is required (so result cannot be guaranteed if smth delay or prevent window from closure):
Example of JSFiddle (Tested on lates Safari, FF, Chrome, Edge and IE11 )
var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write(`<html>
<head><title>CHILD WINDOW/TAB</title></head>
<body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener('load',() => {
document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
setTimeout(()=>{
document.querySelector('.status').innerHTML += getChildWindowStatus();
},1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
alert(getChildWindowStatus());
}
function getChildWindowStatus() {
if (win.closed) {
return 'Child window has been closed!';
} else {
return 'Child window has not been closed!';
}
}
There have been updates to the browser to better tack the user when leaving the app. The event 'visibilitychange' lets you tack when a page is being hidden from another tab or being closed. You can track the document visibility state. The property document.visibilityState will return the current state. You will need to track the sign in and out but its closer to the goal.
This is supported by more newer browser but safari (as we know) never conforms to standards. You can use 'pageshow' and 'pagehide' to work in safari.
You can even use new API's like sendBeacon to send a one way request to the server when the tab is being closed and shouldn't expect a response.
I build a quick port of a class I use to track this. I had to remove some calls in the framework so it might be buggy however this should get you started.
export class UserLoginStatus
{
/**
* This will add the events and sign the user in.
*/
constructor()
{
this.addEvents();
this.signIn();
}
/**
* This will check if the browser is safari.
*
* #returns {bool}
*/
isSafari()
{
if(navigator && /Safari/.test(navigator.userAgent) && /Chrome/.test(navigator.userAgent))
{
return (/Google Inc/.test(navigator.vendor) === false);
}
return false;
}
/**
* This will setup the events array by browser.
*
* #returns {array}
*/
setupEvents()
{
let events = [
['visibilitychange', document, () =>
{
if (document.visibilityState === 'visible')
{
this.signIn();
return;
}
this.signOut();
}]
];
// we need to setup events for safari
if(this.isSafari())
{
events.push(['pageshow', window, (e) =>
{
if(e.persisted === false)
{
this.signIn();
}
}]);
events.push(['pagehide', window, (e) =>
{
if(e.persisted === false)
{
this.signOut();
}
}]);
}
return events;
}
/**
* This will add the events.
*/
addEvents()
{
let events = this.setupEvents();
if(!events || events.length < 1)
{
return;
}
for(var i = 0, length = events.length; i < length; i++)
{
var event = events[i];
if(!event)
{
continue;
}
event[1].addEventListener(event[0], event[3]);
}
}
/**
*
* #param {string} url
* #param {string} params
*/
async fetch(url, params)
{
await fetch(url,
{
method: 'POST',
body: JSON.stringify(params)
});
}
/**
* This will sign in the user.
*/
signIn()
{
// user is the app
const url = '/auth/login';
let params = 'userId=' + data.userId;
this.fetch(url, params);
}
/**
* This will sign out the user.
*/
signOut()
{
// user is leaving the app
const url = '/auth/logout';
let params = 'userId=' + data.userId;
if(!('sendBeacon' in window.navigator))
{
// normal ajax request here
this.fetch(url, params);
return;
}
// use a beacon for a more modern request the does not return a response
navigator.sendBeacon(url, new URLSearchParams(params));
}
}
My approach would be along these lines:
Listen for changes in the url with onpopstate and set a sessionStorage variable with 1
Listen for page load and set that sessionStorage variable to 0
On beforeunload, check if the variable is 0. If so it means that the user is closing and not changing url.
This is still a roundabout way to go, but makes sense to me
As #jAndy mentioned, there is no properly javascript code to detect a window being closed.
I started from what #Syno had proposed.
I had pass though a situation like that and provided you follow these steps, you'll be able to detect it.
I tested it on Chrome 67+ and Firefox 61+.
var wrapper = function () { //ignore this
var closing_window = false;
$(window).on('focus', function () {
closing_window = false;
//if the user interacts with the window, then the window is not being
//closed
});
$(window).on('blur', function () {
closing_window = true;
if (!document.hidden) { //when the window is being minimized
closing_window = false;
}
$(window).on('resize', function (e) { //when the window is being maximized
closing_window = false;
});
$(window).off('resize'); //avoid multiple listening
});
$('html').on('mouseleave', function () {
closing_window = true;
//if the user is leaving html, we have more reasons to believe that he's
//leaving or thinking about closing the window
});
$('html').on('mouseenter', function () {
closing_window = false;
//if the user's mouse its on the page, it means you don't need to logout
//them, didn't it?
});
$(document).on('keydown', function (e) {
if (e.keyCode == 91 || e.keyCode == 18) {
closing_window = false; //shortcuts for ALT+TAB and Window key
}
if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
}
});
// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
closing_window = false;
});
// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
closing_window = false;
});
var toDoWhenClosing = function() {
//write a code here likes a user logout, example:
//$.ajax({
// url: '/MyController/MyLogOutAction',
// async: false,
// data: {
// },
// error: function () {
// },
// success: function (data) {
// },
//});
};
window.onbeforeunload = function () {
if (closing_window) {
toDoWhenClosing();
}
};
};
try this,
I am sure this will work for you.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
$(function() {
try{
opera.setOverrideHistoryNavigationMode('compatible');
history.navigationMode = 'compatible';
}catch(e){}
function ReturnMessage()
{
return "wait";
}
function UnBindWindow()
{
$(window).unbind('beforeunload', ReturnMessage);
}
$(window).bind('beforeunload',ReturnMessage );
});
</script>
Try this. It will work. jquery unload method is depreceted.
window.onbeforeunload = function(event) {
event.returnValue = "Write something clever here..";
};

Javascript code for detecting tab or browser closing [duplicate]

Is there any cross-browser JavaScript/jQuery code to detect if the browser or a browser tab is being closed, but not due to a link being clicked?
If I get you correctly, you want to know when a tab/window is effectively closed. Well, AFAIK the only way in JavaScript to detect that is to use either onunload or onbeforeunload events.
Unfortunately (or fortunately?), those events are also fired when you leave a site over a link or your browsers back button. So this is the best answer I can give, I don't think you can natively detect a pure close in JavaScript. Correct me if I'm wrong here.
From MDN Documentation
For some reasons, Webkit-based browsers don't follow the spec for the dialog box. An almost cross-working example would be close from the below example.
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
This example for handling all browsers.
Simple Solution
window.onbeforeunload = function () {
return "Do you really want to close?";
};
<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">
var myclose = false;
function ConfirmClose()
{
if (event.clientY < 0)
{
event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
setTimeout('myclose=false',10);
myclose=true;
}
}
function HandleOnClose()
{
if (myclose==true)
{
//the url of your logout page which invalidate session on logout
location.replace('/contextpath/j_spring_security_logout') ;
}
}
//This is working in IE7, if you are closing tab or browser with only one tab
For similar tasks, you can use sessionStorage to store data locally until the browser tab is closed.
The sessionStorage object stores data for only one session (the data is deleted when the browser tab is closed).(W3Schools)
This is my pen.
<div id="Notice">
<span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
$("#Notice").click(function() {
//set sessionStorage on click
sessionStorage.setItem("dismissNotice", "Hello");
$("#Notice").remove();
});
if (sessionStorage.getItem("dismissNotice"))
//When sessionStorage is set Do stuff...
$("#Notice").remove();
</script>
I needed to automatically log the user out when the browser or tab closes, but not when the user navigates to other links. I also did not want a confirmation prompt shown when that happens. After struggling with this for a while, especially with IE and Edge, here's what I ended doing (checked working with IE 11, Edge, Chrome, and Firefox) after basing off the approach by this answer.
First, start a countdown timer on the server in the beforeunload event handler in JS. The ajax calls need to be synchronous for IE and Edge to work properly. You also need to use return; to prevent the confirmation dialog from showing like this:
window.addEventListener("beforeunload", function (e) {
$.ajax({
type: "POST",
url: startTimerUrl,
async: false
});
return;
});
Starting the timer sets the cancelLogout flag to false. If the user refreshes the page or navigates to another internal link, the cancelLogout flag on the server is set to true. Once the timer event elapses, it checks the cancelLogout flag to see if the logout event has been cancelled. If the timer has been cancelled, then it would stop the timer. If the browser or tab was closed, then the cancelLogout flag would remain false and the event handler would log the user out.
Implementation note: I'm using ASP.NET MVC 5 and I'm cancelling logout in an overridden Controller.OnActionExecuted() method.
I found a way, that works on all of my browsers.
Tested on following versions:
Firefox 57, Internet Explorer 11, Edge 41, one of the latested Chrome (it won't show my version)
Note: onbeforeunload fires if you leave the page in any way possible (refresh, close browser, redirect, link, submit..). If you only want it to happen on browser close, simply bind the event handlers.
$(document).ready(function(){
var validNavigation = false;
// Attach the event keypress to exclude the F5 refresh (includes normal 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;
});
window.onbeforeunload = function() {
if (!validNavigation) {
// -------> code comes here
}
};
});
There is no event, but there is a property window.closed which is supported in all major browsers as of the time of this writing. Thus if you really needed to know you could poll the window to check that property.
if(myWindow.closed){do things}
Note:
Polling anything is generally not the best solution. The window.onbeforeunload event should be used if possible, the only caveat being that it also fires if you navigate away.
Sorry, I was not able to add a comment to one of existing answers, but in case you wanted to implement a kind of warning dialog, I just wanted to mention that any event handler function has an argument - event. In your case you can call event.preventDefault() to disallow leaving the page automatically, then issue your own dialog. I consider this a way better option than using standard ugly and insecure alert(). I personally implemented my own set of dialog boxes based on kendoWindow object (Telerik's Kendo UI, which is almost fully open-sourced, except of kendoGrid and kendoEditor). You can also use dialog boxes from jQuery UI. Please note though, that such things are asynchronous, and you will need to bind a handler to onclick event of every button, but this is all quite easy to implement.
However, I do agree that the lack of the real close event is terrible: if you, for instance, want to reset your session state at the back-end only on case of the real close, it's a problem.
$(window).unload( function () { alert("Bye now!"); } );
onunload is the answer for Chrome. According to caniuse its crossbrowser. But not all browsers react the same.
window.onunload = function(){
alert("The window is closing now!");
}
developer.mozilla.org
These events fire when the window is unloading its content and resources.
For Chrome:
onunload executes only on page close. It doesn't execute even on page refresh and on navigating to a different page.
For Firefox v86.0:
It wouldn't execute at all. Page refresh, navigating away, closing browser tab, closing browser, nothing.
Since no one has mentioned it yet (8+ years later): A WebSocket can be another effective way to detect a closed tab. As long as the tab is open and pointed at the host, the client is able to maintain an active WebSocket connection to the host.
Caveat: Please note that this solution is really only viable for a project if a WebSocket doesn't require any additional significant overhead from what you are already doing.
Within a sensible timeout period (e.g. 2 minutes), the server side can determine that the client has gone away after the WebSocket has disconnected and perform whatever action is desired such as removing uploaded temp files. (In my extremely specialized use-case, my goal was to terminate a localhost app server three seconds after the WebSocket connection drops and all CGI/FastCGI activity terminates - any other keep-alive connections don't affect me.)
I had problems getting the onunload event handler to work properly with beacons (as recommended by this answer). Closing the tab did not appear to trigger the beacon and open tabs triggered it in ways that could potentially cause problems. A WebSocket solved the problem I was running into more cleanly because the connection closes roughly around the same time that the tab closes and switching pages within the application simply opens a new WebSocket connection well within the delay window.
It can be used to alert the user if some data is unsaved or something like that. This method works when the tab is closed or when the browser is closed, or webpage refresh.
It won't work unless the user has not interacted with the webpage, this is a mechanism to fight malicious websites..... there will be no popup unless you atleast make a click or touch on the website window.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<textarea placeholder = "Write...."></textarea>
</form>
<script type="text/javascript">
window.addEventListener('beforeunload', function (e) {
e.returnValue = '';
});
</script>
</body>
</html>
window.onbeforeunload = function() {
console.log('event');
return false; //here also can be string, that will be shown to the user
}
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
e = e || window.event;
var localStorageTime = localStorage.getItem('storagetime')
if(localStorageTime!=null && localStorageTime!=undefined){
var currentTime = new Date().getTime(),
timeDifference = currentTime - localStorageTime;
if(timeDifference<25){//Browser Closed
localStorage.removeItem('storagetime');
}else{//Browser Tab Closed
localStorage.setItem('storagetime',new Date().getTime());
}
}else{
localStorage.setItem('storagetime',new Date().getTime());
}
});
JSFiddle Link
Hi all, I was able to achieve 'Detect Browser and Tab Close Event' clicks by using browser local storage and timestamp. Hope all of you will get solved your problems by using this solution.
After my initial research i found that when we close a browser, the browser will close all the tabs one by one to completely close the browser. Hence, i observed that there will be very little time delay between closing the tabs. So I taken this time delay as my main validation point and able to achieve the browser and tab close event detection.
I tested it on Chrome Browser Version 76.0.3809.132 and found working
:) Vote Up if you found my answer helpful....
I have tried all above solutions, none of them really worked for me, specially because there are some Telerik components in my project which have 'Close' button for popup windows, and it calls 'beforeunload' event. Also, button selector does not work properly when you have Telerik grid in your page (I mean buttons inside the grid) So, I couldn't use any of above suggestions. Finally this is the solution worked for me.
I have added an onUnload event on the body tag of _Layout.cshtml. Something like this:
<body onUnload="LogOff()">
and then add the LogOff function to redirect to Account/LogOff which is a built-in method in Asp.Net MVC. Now, when I close the browser or tab, it redirect to LogOff method and user have to login when returns. I have tested it in both Chrome & Firefox. And it works!
function LogOff() {
$.ajax({
url: "/Account/LogOff",
success: function (result) {
}
});
}
window.onbeforeunload = function ()
{
if (isProcess > 0)
{
return true;
}
else
{
//do something
}
};
This function show a confirmation dialog box if you close window or refresh page during any process in browser.This function work in all browsers.You have to set isProcess var in your ajax process.
It is possible to check it with the help of window.closed in an event handler on 'unload' event like this, but timeout usage is required (so result cannot be guaranteed if smth delay or prevent window from closure):
Example of JSFiddle (Tested on lates Safari, FF, Chrome, Edge and IE11 )
var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write(`<html>
<head><title>CHILD WINDOW/TAB</title></head>
<body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener('load',() => {
document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
setTimeout(()=>{
document.querySelector('.status').innerHTML += getChildWindowStatus();
},1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
alert(getChildWindowStatus());
}
function getChildWindowStatus() {
if (win.closed) {
return 'Child window has been closed!';
} else {
return 'Child window has not been closed!';
}
}
There have been updates to the browser to better tack the user when leaving the app. The event 'visibilitychange' lets you tack when a page is being hidden from another tab or being closed. You can track the document visibility state. The property document.visibilityState will return the current state. You will need to track the sign in and out but its closer to the goal.
This is supported by more newer browser but safari (as we know) never conforms to standards. You can use 'pageshow' and 'pagehide' to work in safari.
You can even use new API's like sendBeacon to send a one way request to the server when the tab is being closed and shouldn't expect a response.
I build a quick port of a class I use to track this. I had to remove some calls in the framework so it might be buggy however this should get you started.
export class UserLoginStatus
{
/**
* This will add the events and sign the user in.
*/
constructor()
{
this.addEvents();
this.signIn();
}
/**
* This will check if the browser is safari.
*
* #returns {bool}
*/
isSafari()
{
if(navigator && /Safari/.test(navigator.userAgent) && /Chrome/.test(navigator.userAgent))
{
return (/Google Inc/.test(navigator.vendor) === false);
}
return false;
}
/**
* This will setup the events array by browser.
*
* #returns {array}
*/
setupEvents()
{
let events = [
['visibilitychange', document, () =>
{
if (document.visibilityState === 'visible')
{
this.signIn();
return;
}
this.signOut();
}]
];
// we need to setup events for safari
if(this.isSafari())
{
events.push(['pageshow', window, (e) =>
{
if(e.persisted === false)
{
this.signIn();
}
}]);
events.push(['pagehide', window, (e) =>
{
if(e.persisted === false)
{
this.signOut();
}
}]);
}
return events;
}
/**
* This will add the events.
*/
addEvents()
{
let events = this.setupEvents();
if(!events || events.length < 1)
{
return;
}
for(var i = 0, length = events.length; i < length; i++)
{
var event = events[i];
if(!event)
{
continue;
}
event[1].addEventListener(event[0], event[3]);
}
}
/**
*
* #param {string} url
* #param {string} params
*/
async fetch(url, params)
{
await fetch(url,
{
method: 'POST',
body: JSON.stringify(params)
});
}
/**
* This will sign in the user.
*/
signIn()
{
// user is the app
const url = '/auth/login';
let params = 'userId=' + data.userId;
this.fetch(url, params);
}
/**
* This will sign out the user.
*/
signOut()
{
// user is leaving the app
const url = '/auth/logout';
let params = 'userId=' + data.userId;
if(!('sendBeacon' in window.navigator))
{
// normal ajax request here
this.fetch(url, params);
return;
}
// use a beacon for a more modern request the does not return a response
navigator.sendBeacon(url, new URLSearchParams(params));
}
}
My approach would be along these lines:
Listen for changes in the url with onpopstate and set a sessionStorage variable with 1
Listen for page load and set that sessionStorage variable to 0
On beforeunload, check if the variable is 0. If so it means that the user is closing and not changing url.
This is still a roundabout way to go, but makes sense to me
As #jAndy mentioned, there is no properly javascript code to detect a window being closed.
I started from what #Syno had proposed.
I had pass though a situation like that and provided you follow these steps, you'll be able to detect it.
I tested it on Chrome 67+ and Firefox 61+.
var wrapper = function () { //ignore this
var closing_window = false;
$(window).on('focus', function () {
closing_window = false;
//if the user interacts with the window, then the window is not being
//closed
});
$(window).on('blur', function () {
closing_window = true;
if (!document.hidden) { //when the window is being minimized
closing_window = false;
}
$(window).on('resize', function (e) { //when the window is being maximized
closing_window = false;
});
$(window).off('resize'); //avoid multiple listening
});
$('html').on('mouseleave', function () {
closing_window = true;
//if the user is leaving html, we have more reasons to believe that he's
//leaving or thinking about closing the window
});
$('html').on('mouseenter', function () {
closing_window = false;
//if the user's mouse its on the page, it means you don't need to logout
//them, didn't it?
});
$(document).on('keydown', function (e) {
if (e.keyCode == 91 || e.keyCode == 18) {
closing_window = false; //shortcuts for ALT+TAB and Window key
}
if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
}
});
// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
closing_window = false;
});
// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
closing_window = false;
});
var toDoWhenClosing = function() {
//write a code here likes a user logout, example:
//$.ajax({
// url: '/MyController/MyLogOutAction',
// async: false,
// data: {
// },
// error: function () {
// },
// success: function (data) {
// },
//});
};
window.onbeforeunload = function () {
if (closing_window) {
toDoWhenClosing();
}
};
};
try this,
I am sure this will work for you.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
$(function() {
try{
opera.setOverrideHistoryNavigationMode('compatible');
history.navigationMode = 'compatible';
}catch(e){}
function ReturnMessage()
{
return "wait";
}
function UnBindWindow()
{
$(window).unbind('beforeunload', ReturnMessage);
}
$(window).bind('beforeunload',ReturnMessage );
});
</script>
Try this. It will work. jquery unload method is depreceted.
window.onbeforeunload = function(event) {
event.returnValue = "Write something clever here..";
};

javascript - Differentiate between browser close/back or forward [duplicate]

Is there any cross-browser JavaScript/jQuery code to detect if the browser or a browser tab is being closed, but not due to a link being clicked?
If I get you correctly, you want to know when a tab/window is effectively closed. Well, AFAIK the only way in JavaScript to detect that is to use either onunload or onbeforeunload events.
Unfortunately (or fortunately?), those events are also fired when you leave a site over a link or your browsers back button. So this is the best answer I can give, I don't think you can natively detect a pure close in JavaScript. Correct me if I'm wrong here.
From MDN Documentation
For some reasons, Webkit-based browsers don't follow the spec for the dialog box. An almost cross-working example would be close from the below example.
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
This example for handling all browsers.
Simple Solution
window.onbeforeunload = function () {
return "Do you really want to close?";
};
<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">
var myclose = false;
function ConfirmClose()
{
if (event.clientY < 0)
{
event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
setTimeout('myclose=false',10);
myclose=true;
}
}
function HandleOnClose()
{
if (myclose==true)
{
//the url of your logout page which invalidate session on logout
location.replace('/contextpath/j_spring_security_logout') ;
}
}
//This is working in IE7, if you are closing tab or browser with only one tab
For similar tasks, you can use sessionStorage to store data locally until the browser tab is closed.
The sessionStorage object stores data for only one session (the data is deleted when the browser tab is closed).(W3Schools)
This is my pen.
<div id="Notice">
<span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
$("#Notice").click(function() {
//set sessionStorage on click
sessionStorage.setItem("dismissNotice", "Hello");
$("#Notice").remove();
});
if (sessionStorage.getItem("dismissNotice"))
//When sessionStorage is set Do stuff...
$("#Notice").remove();
</script>
I needed to automatically log the user out when the browser or tab closes, but not when the user navigates to other links. I also did not want a confirmation prompt shown when that happens. After struggling with this for a while, especially with IE and Edge, here's what I ended doing (checked working with IE 11, Edge, Chrome, and Firefox) after basing off the approach by this answer.
First, start a countdown timer on the server in the beforeunload event handler in JS. The ajax calls need to be synchronous for IE and Edge to work properly. You also need to use return; to prevent the confirmation dialog from showing like this:
window.addEventListener("beforeunload", function (e) {
$.ajax({
type: "POST",
url: startTimerUrl,
async: false
});
return;
});
Starting the timer sets the cancelLogout flag to false. If the user refreshes the page or navigates to another internal link, the cancelLogout flag on the server is set to true. Once the timer event elapses, it checks the cancelLogout flag to see if the logout event has been cancelled. If the timer has been cancelled, then it would stop the timer. If the browser or tab was closed, then the cancelLogout flag would remain false and the event handler would log the user out.
Implementation note: I'm using ASP.NET MVC 5 and I'm cancelling logout in an overridden Controller.OnActionExecuted() method.
I found a way, that works on all of my browsers.
Tested on following versions:
Firefox 57, Internet Explorer 11, Edge 41, one of the latested Chrome (it won't show my version)
Note: onbeforeunload fires if you leave the page in any way possible (refresh, close browser, redirect, link, submit..). If you only want it to happen on browser close, simply bind the event handlers.
$(document).ready(function(){
var validNavigation = false;
// Attach the event keypress to exclude the F5 refresh (includes normal 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;
});
window.onbeforeunload = function() {
if (!validNavigation) {
// -------> code comes here
}
};
});
There is no event, but there is a property window.closed which is supported in all major browsers as of the time of this writing. Thus if you really needed to know you could poll the window to check that property.
if(myWindow.closed){do things}
Note:
Polling anything is generally not the best solution. The window.onbeforeunload event should be used if possible, the only caveat being that it also fires if you navigate away.
Sorry, I was not able to add a comment to one of existing answers, but in case you wanted to implement a kind of warning dialog, I just wanted to mention that any event handler function has an argument - event. In your case you can call event.preventDefault() to disallow leaving the page automatically, then issue your own dialog. I consider this a way better option than using standard ugly and insecure alert(). I personally implemented my own set of dialog boxes based on kendoWindow object (Telerik's Kendo UI, which is almost fully open-sourced, except of kendoGrid and kendoEditor). You can also use dialog boxes from jQuery UI. Please note though, that such things are asynchronous, and you will need to bind a handler to onclick event of every button, but this is all quite easy to implement.
However, I do agree that the lack of the real close event is terrible: if you, for instance, want to reset your session state at the back-end only on case of the real close, it's a problem.
$(window).unload( function () { alert("Bye now!"); } );
onunload is the answer for Chrome. According to caniuse its crossbrowser. But not all browsers react the same.
window.onunload = function(){
alert("The window is closing now!");
}
developer.mozilla.org
These events fire when the window is unloading its content and resources.
For Chrome:
onunload executes only on page close. It doesn't execute even on page refresh and on navigating to a different page.
For Firefox v86.0:
It wouldn't execute at all. Page refresh, navigating away, closing browser tab, closing browser, nothing.
Since no one has mentioned it yet (8+ years later): A WebSocket can be another effective way to detect a closed tab. As long as the tab is open and pointed at the host, the client is able to maintain an active WebSocket connection to the host.
Caveat: Please note that this solution is really only viable for a project if a WebSocket doesn't require any additional significant overhead from what you are already doing.
Within a sensible timeout period (e.g. 2 minutes), the server side can determine that the client has gone away after the WebSocket has disconnected and perform whatever action is desired such as removing uploaded temp files. (In my extremely specialized use-case, my goal was to terminate a localhost app server three seconds after the WebSocket connection drops and all CGI/FastCGI activity terminates - any other keep-alive connections don't affect me.)
I had problems getting the onunload event handler to work properly with beacons (as recommended by this answer). Closing the tab did not appear to trigger the beacon and open tabs triggered it in ways that could potentially cause problems. A WebSocket solved the problem I was running into more cleanly because the connection closes roughly around the same time that the tab closes and switching pages within the application simply opens a new WebSocket connection well within the delay window.
It can be used to alert the user if some data is unsaved or something like that. This method works when the tab is closed or when the browser is closed, or webpage refresh.
It won't work unless the user has not interacted with the webpage, this is a mechanism to fight malicious websites..... there will be no popup unless you atleast make a click or touch on the website window.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<textarea placeholder = "Write...."></textarea>
</form>
<script type="text/javascript">
window.addEventListener('beforeunload', function (e) {
e.returnValue = '';
});
</script>
</body>
</html>
window.onbeforeunload = function() {
console.log('event');
return false; //here also can be string, that will be shown to the user
}
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
e = e || window.event;
var localStorageTime = localStorage.getItem('storagetime')
if(localStorageTime!=null && localStorageTime!=undefined){
var currentTime = new Date().getTime(),
timeDifference = currentTime - localStorageTime;
if(timeDifference<25){//Browser Closed
localStorage.removeItem('storagetime');
}else{//Browser Tab Closed
localStorage.setItem('storagetime',new Date().getTime());
}
}else{
localStorage.setItem('storagetime',new Date().getTime());
}
});
JSFiddle Link
Hi all, I was able to achieve 'Detect Browser and Tab Close Event' clicks by using browser local storage and timestamp. Hope all of you will get solved your problems by using this solution.
After my initial research i found that when we close a browser, the browser will close all the tabs one by one to completely close the browser. Hence, i observed that there will be very little time delay between closing the tabs. So I taken this time delay as my main validation point and able to achieve the browser and tab close event detection.
I tested it on Chrome Browser Version 76.0.3809.132 and found working
:) Vote Up if you found my answer helpful....
I have tried all above solutions, none of them really worked for me, specially because there are some Telerik components in my project which have 'Close' button for popup windows, and it calls 'beforeunload' event. Also, button selector does not work properly when you have Telerik grid in your page (I mean buttons inside the grid) So, I couldn't use any of above suggestions. Finally this is the solution worked for me.
I have added an onUnload event on the body tag of _Layout.cshtml. Something like this:
<body onUnload="LogOff()">
and then add the LogOff function to redirect to Account/LogOff which is a built-in method in Asp.Net MVC. Now, when I close the browser or tab, it redirect to LogOff method and user have to login when returns. I have tested it in both Chrome & Firefox. And it works!
function LogOff() {
$.ajax({
url: "/Account/LogOff",
success: function (result) {
}
});
}
window.onbeforeunload = function ()
{
if (isProcess > 0)
{
return true;
}
else
{
//do something
}
};
This function show a confirmation dialog box if you close window or refresh page during any process in browser.This function work in all browsers.You have to set isProcess var in your ajax process.
It is possible to check it with the help of window.closed in an event handler on 'unload' event like this, but timeout usage is required (so result cannot be guaranteed if smth delay or prevent window from closure):
Example of JSFiddle (Tested on lates Safari, FF, Chrome, Edge and IE11 )
var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write(`<html>
<head><title>CHILD WINDOW/TAB</title></head>
<body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener('load',() => {
document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
setTimeout(()=>{
document.querySelector('.status').innerHTML += getChildWindowStatus();
},1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
alert(getChildWindowStatus());
}
function getChildWindowStatus() {
if (win.closed) {
return 'Child window has been closed!';
} else {
return 'Child window has not been closed!';
}
}
There have been updates to the browser to better tack the user when leaving the app. The event 'visibilitychange' lets you tack when a page is being hidden from another tab or being closed. You can track the document visibility state. The property document.visibilityState will return the current state. You will need to track the sign in and out but its closer to the goal.
This is supported by more newer browser but safari (as we know) never conforms to standards. You can use 'pageshow' and 'pagehide' to work in safari.
You can even use new API's like sendBeacon to send a one way request to the server when the tab is being closed and shouldn't expect a response.
I build a quick port of a class I use to track this. I had to remove some calls in the framework so it might be buggy however this should get you started.
export class UserLoginStatus
{
/**
* This will add the events and sign the user in.
*/
constructor()
{
this.addEvents();
this.signIn();
}
/**
* This will check if the browser is safari.
*
* #returns {bool}
*/
isSafari()
{
if(navigator && /Safari/.test(navigator.userAgent) && /Chrome/.test(navigator.userAgent))
{
return (/Google Inc/.test(navigator.vendor) === false);
}
return false;
}
/**
* This will setup the events array by browser.
*
* #returns {array}
*/
setupEvents()
{
let events = [
['visibilitychange', document, () =>
{
if (document.visibilityState === 'visible')
{
this.signIn();
return;
}
this.signOut();
}]
];
// we need to setup events for safari
if(this.isSafari())
{
events.push(['pageshow', window, (e) =>
{
if(e.persisted === false)
{
this.signIn();
}
}]);
events.push(['pagehide', window, (e) =>
{
if(e.persisted === false)
{
this.signOut();
}
}]);
}
return events;
}
/**
* This will add the events.
*/
addEvents()
{
let events = this.setupEvents();
if(!events || events.length < 1)
{
return;
}
for(var i = 0, length = events.length; i < length; i++)
{
var event = events[i];
if(!event)
{
continue;
}
event[1].addEventListener(event[0], event[3]);
}
}
/**
*
* #param {string} url
* #param {string} params
*/
async fetch(url, params)
{
await fetch(url,
{
method: 'POST',
body: JSON.stringify(params)
});
}
/**
* This will sign in the user.
*/
signIn()
{
// user is the app
const url = '/auth/login';
let params = 'userId=' + data.userId;
this.fetch(url, params);
}
/**
* This will sign out the user.
*/
signOut()
{
// user is leaving the app
const url = '/auth/logout';
let params = 'userId=' + data.userId;
if(!('sendBeacon' in window.navigator))
{
// normal ajax request here
this.fetch(url, params);
return;
}
// use a beacon for a more modern request the does not return a response
navigator.sendBeacon(url, new URLSearchParams(params));
}
}
My approach would be along these lines:
Listen for changes in the url with onpopstate and set a sessionStorage variable with 1
Listen for page load and set that sessionStorage variable to 0
On beforeunload, check if the variable is 0. If so it means that the user is closing and not changing url.
This is still a roundabout way to go, but makes sense to me
As #jAndy mentioned, there is no properly javascript code to detect a window being closed.
I started from what #Syno had proposed.
I had pass though a situation like that and provided you follow these steps, you'll be able to detect it.
I tested it on Chrome 67+ and Firefox 61+.
var wrapper = function () { //ignore this
var closing_window = false;
$(window).on('focus', function () {
closing_window = false;
//if the user interacts with the window, then the window is not being
//closed
});
$(window).on('blur', function () {
closing_window = true;
if (!document.hidden) { //when the window is being minimized
closing_window = false;
}
$(window).on('resize', function (e) { //when the window is being maximized
closing_window = false;
});
$(window).off('resize'); //avoid multiple listening
});
$('html').on('mouseleave', function () {
closing_window = true;
//if the user is leaving html, we have more reasons to believe that he's
//leaving or thinking about closing the window
});
$('html').on('mouseenter', function () {
closing_window = false;
//if the user's mouse its on the page, it means you don't need to logout
//them, didn't it?
});
$(document).on('keydown', function (e) {
if (e.keyCode == 91 || e.keyCode == 18) {
closing_window = false; //shortcuts for ALT+TAB and Window key
}
if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
}
});
// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
closing_window = false;
});
// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
closing_window = false;
});
var toDoWhenClosing = function() {
//write a code here likes a user logout, example:
//$.ajax({
// url: '/MyController/MyLogOutAction',
// async: false,
// data: {
// },
// error: function () {
// },
// success: function (data) {
// },
//});
};
window.onbeforeunload = function () {
if (closing_window) {
toDoWhenClosing();
}
};
};
try this,
I am sure this will work for you.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
$(function() {
try{
opera.setOverrideHistoryNavigationMode('compatible');
history.navigationMode = 'compatible';
}catch(e){}
function ReturnMessage()
{
return "wait";
}
function UnBindWindow()
{
$(window).unbind('beforeunload', ReturnMessage);
}
$(window).bind('beforeunload',ReturnMessage );
});
</script>
Try this. It will work. jquery unload method is depreceted.
window.onbeforeunload = function(event) {
event.returnValue = "Write something clever here..";
};

'window.onbeforeunload' works even when am refreshing the page [duplicate]

Is there any cross-browser JavaScript/jQuery code to detect if the browser or a browser tab is being closed, but not due to a link being clicked?
If I get you correctly, you want to know when a tab/window is effectively closed. Well, AFAIK the only way in JavaScript to detect that is to use either onunload or onbeforeunload events.
Unfortunately (or fortunately?), those events are also fired when you leave a site over a link or your browsers back button. So this is the best answer I can give, I don't think you can natively detect a pure close in JavaScript. Correct me if I'm wrong here.
From MDN Documentation
For some reasons, Webkit-based browsers don't follow the spec for the dialog box. An almost cross-working example would be close from the below example.
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
This example for handling all browsers.
Simple Solution
window.onbeforeunload = function () {
return "Do you really want to close?";
};
<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">
var myclose = false;
function ConfirmClose()
{
if (event.clientY < 0)
{
event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
setTimeout('myclose=false',10);
myclose=true;
}
}
function HandleOnClose()
{
if (myclose==true)
{
//the url of your logout page which invalidate session on logout
location.replace('/contextpath/j_spring_security_logout') ;
}
}
//This is working in IE7, if you are closing tab or browser with only one tab
For similar tasks, you can use sessionStorage to store data locally until the browser tab is closed.
The sessionStorage object stores data for only one session (the data is deleted when the browser tab is closed).(W3Schools)
This is my pen.
<div id="Notice">
<span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
$("#Notice").click(function() {
//set sessionStorage on click
sessionStorage.setItem("dismissNotice", "Hello");
$("#Notice").remove();
});
if (sessionStorage.getItem("dismissNotice"))
//When sessionStorage is set Do stuff...
$("#Notice").remove();
</script>
I needed to automatically log the user out when the browser or tab closes, but not when the user navigates to other links. I also did not want a confirmation prompt shown when that happens. After struggling with this for a while, especially with IE and Edge, here's what I ended doing (checked working with IE 11, Edge, Chrome, and Firefox) after basing off the approach by this answer.
First, start a countdown timer on the server in the beforeunload event handler in JS. The ajax calls need to be synchronous for IE and Edge to work properly. You also need to use return; to prevent the confirmation dialog from showing like this:
window.addEventListener("beforeunload", function (e) {
$.ajax({
type: "POST",
url: startTimerUrl,
async: false
});
return;
});
Starting the timer sets the cancelLogout flag to false. If the user refreshes the page or navigates to another internal link, the cancelLogout flag on the server is set to true. Once the timer event elapses, it checks the cancelLogout flag to see if the logout event has been cancelled. If the timer has been cancelled, then it would stop the timer. If the browser or tab was closed, then the cancelLogout flag would remain false and the event handler would log the user out.
Implementation note: I'm using ASP.NET MVC 5 and I'm cancelling logout in an overridden Controller.OnActionExecuted() method.
I found a way, that works on all of my browsers.
Tested on following versions:
Firefox 57, Internet Explorer 11, Edge 41, one of the latested Chrome (it won't show my version)
Note: onbeforeunload fires if you leave the page in any way possible (refresh, close browser, redirect, link, submit..). If you only want it to happen on browser close, simply bind the event handlers.
$(document).ready(function(){
var validNavigation = false;
// Attach the event keypress to exclude the F5 refresh (includes normal 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;
});
window.onbeforeunload = function() {
if (!validNavigation) {
// -------> code comes here
}
};
});
There is no event, but there is a property window.closed which is supported in all major browsers as of the time of this writing. Thus if you really needed to know you could poll the window to check that property.
if(myWindow.closed){do things}
Note:
Polling anything is generally not the best solution. The window.onbeforeunload event should be used if possible, the only caveat being that it also fires if you navigate away.
Sorry, I was not able to add a comment to one of existing answers, but in case you wanted to implement a kind of warning dialog, I just wanted to mention that any event handler function has an argument - event. In your case you can call event.preventDefault() to disallow leaving the page automatically, then issue your own dialog. I consider this a way better option than using standard ugly and insecure alert(). I personally implemented my own set of dialog boxes based on kendoWindow object (Telerik's Kendo UI, which is almost fully open-sourced, except of kendoGrid and kendoEditor). You can also use dialog boxes from jQuery UI. Please note though, that such things are asynchronous, and you will need to bind a handler to onclick event of every button, but this is all quite easy to implement.
However, I do agree that the lack of the real close event is terrible: if you, for instance, want to reset your session state at the back-end only on case of the real close, it's a problem.
$(window).unload( function () { alert("Bye now!"); } );
onunload is the answer for Chrome. According to caniuse its crossbrowser. But not all browsers react the same.
window.onunload = function(){
alert("The window is closing now!");
}
developer.mozilla.org
These events fire when the window is unloading its content and resources.
For Chrome:
onunload executes only on page close. It doesn't execute even on page refresh and on navigating to a different page.
For Firefox v86.0:
It wouldn't execute at all. Page refresh, navigating away, closing browser tab, closing browser, nothing.
Since no one has mentioned it yet (8+ years later): A WebSocket can be another effective way to detect a closed tab. As long as the tab is open and pointed at the host, the client is able to maintain an active WebSocket connection to the host.
Caveat: Please note that this solution is really only viable for a project if a WebSocket doesn't require any additional significant overhead from what you are already doing.
Within a sensible timeout period (e.g. 2 minutes), the server side can determine that the client has gone away after the WebSocket has disconnected and perform whatever action is desired such as removing uploaded temp files. (In my extremely specialized use-case, my goal was to terminate a localhost app server three seconds after the WebSocket connection drops and all CGI/FastCGI activity terminates - any other keep-alive connections don't affect me.)
I had problems getting the onunload event handler to work properly with beacons (as recommended by this answer). Closing the tab did not appear to trigger the beacon and open tabs triggered it in ways that could potentially cause problems. A WebSocket solved the problem I was running into more cleanly because the connection closes roughly around the same time that the tab closes and switching pages within the application simply opens a new WebSocket connection well within the delay window.
It can be used to alert the user if some data is unsaved or something like that. This method works when the tab is closed or when the browser is closed, or webpage refresh.
It won't work unless the user has not interacted with the webpage, this is a mechanism to fight malicious websites..... there will be no popup unless you atleast make a click or touch on the website window.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<textarea placeholder = "Write...."></textarea>
</form>
<script type="text/javascript">
window.addEventListener('beforeunload', function (e) {
e.returnValue = '';
});
</script>
</body>
</html>
window.onbeforeunload = function() {
console.log('event');
return false; //here also can be string, that will be shown to the user
}
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
e = e || window.event;
var localStorageTime = localStorage.getItem('storagetime')
if(localStorageTime!=null && localStorageTime!=undefined){
var currentTime = new Date().getTime(),
timeDifference = currentTime - localStorageTime;
if(timeDifference<25){//Browser Closed
localStorage.removeItem('storagetime');
}else{//Browser Tab Closed
localStorage.setItem('storagetime',new Date().getTime());
}
}else{
localStorage.setItem('storagetime',new Date().getTime());
}
});
JSFiddle Link
Hi all, I was able to achieve 'Detect Browser and Tab Close Event' clicks by using browser local storage and timestamp. Hope all of you will get solved your problems by using this solution.
After my initial research i found that when we close a browser, the browser will close all the tabs one by one to completely close the browser. Hence, i observed that there will be very little time delay between closing the tabs. So I taken this time delay as my main validation point and able to achieve the browser and tab close event detection.
I tested it on Chrome Browser Version 76.0.3809.132 and found working
:) Vote Up if you found my answer helpful....
I have tried all above solutions, none of them really worked for me, specially because there are some Telerik components in my project which have 'Close' button for popup windows, and it calls 'beforeunload' event. Also, button selector does not work properly when you have Telerik grid in your page (I mean buttons inside the grid) So, I couldn't use any of above suggestions. Finally this is the solution worked for me.
I have added an onUnload event on the body tag of _Layout.cshtml. Something like this:
<body onUnload="LogOff()">
and then add the LogOff function to redirect to Account/LogOff which is a built-in method in Asp.Net MVC. Now, when I close the browser or tab, it redirect to LogOff method and user have to login when returns. I have tested it in both Chrome & Firefox. And it works!
function LogOff() {
$.ajax({
url: "/Account/LogOff",
success: function (result) {
}
});
}
window.onbeforeunload = function ()
{
if (isProcess > 0)
{
return true;
}
else
{
//do something
}
};
This function show a confirmation dialog box if you close window or refresh page during any process in browser.This function work in all browsers.You have to set isProcess var in your ajax process.
It is possible to check it with the help of window.closed in an event handler on 'unload' event like this, but timeout usage is required (so result cannot be guaranteed if smth delay or prevent window from closure):
Example of JSFiddle (Tested on lates Safari, FF, Chrome, Edge and IE11 )
var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write(`<html>
<head><title>CHILD WINDOW/TAB</title></head>
<body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener('load',() => {
document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
setTimeout(()=>{
document.querySelector('.status').innerHTML += getChildWindowStatus();
},1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
alert(getChildWindowStatus());
}
function getChildWindowStatus() {
if (win.closed) {
return 'Child window has been closed!';
} else {
return 'Child window has not been closed!';
}
}
There have been updates to the browser to better tack the user when leaving the app. The event 'visibilitychange' lets you tack when a page is being hidden from another tab or being closed. You can track the document visibility state. The property document.visibilityState will return the current state. You will need to track the sign in and out but its closer to the goal.
This is supported by more newer browser but safari (as we know) never conforms to standards. You can use 'pageshow' and 'pagehide' to work in safari.
You can even use new API's like sendBeacon to send a one way request to the server when the tab is being closed and shouldn't expect a response.
I build a quick port of a class I use to track this. I had to remove some calls in the framework so it might be buggy however this should get you started.
export class UserLoginStatus
{
/**
* This will add the events and sign the user in.
*/
constructor()
{
this.addEvents();
this.signIn();
}
/**
* This will check if the browser is safari.
*
* #returns {bool}
*/
isSafari()
{
if(navigator && /Safari/.test(navigator.userAgent) && /Chrome/.test(navigator.userAgent))
{
return (/Google Inc/.test(navigator.vendor) === false);
}
return false;
}
/**
* This will setup the events array by browser.
*
* #returns {array}
*/
setupEvents()
{
let events = [
['visibilitychange', document, () =>
{
if (document.visibilityState === 'visible')
{
this.signIn();
return;
}
this.signOut();
}]
];
// we need to setup events for safari
if(this.isSafari())
{
events.push(['pageshow', window, (e) =>
{
if(e.persisted === false)
{
this.signIn();
}
}]);
events.push(['pagehide', window, (e) =>
{
if(e.persisted === false)
{
this.signOut();
}
}]);
}
return events;
}
/**
* This will add the events.
*/
addEvents()
{
let events = this.setupEvents();
if(!events || events.length < 1)
{
return;
}
for(var i = 0, length = events.length; i < length; i++)
{
var event = events[i];
if(!event)
{
continue;
}
event[1].addEventListener(event[0], event[3]);
}
}
/**
*
* #param {string} url
* #param {string} params
*/
async fetch(url, params)
{
await fetch(url,
{
method: 'POST',
body: JSON.stringify(params)
});
}
/**
* This will sign in the user.
*/
signIn()
{
// user is the app
const url = '/auth/login';
let params = 'userId=' + data.userId;
this.fetch(url, params);
}
/**
* This will sign out the user.
*/
signOut()
{
// user is leaving the app
const url = '/auth/logout';
let params = 'userId=' + data.userId;
if(!('sendBeacon' in window.navigator))
{
// normal ajax request here
this.fetch(url, params);
return;
}
// use a beacon for a more modern request the does not return a response
navigator.sendBeacon(url, new URLSearchParams(params));
}
}
My approach would be along these lines:
Listen for changes in the url with onpopstate and set a sessionStorage variable with 1
Listen for page load and set that sessionStorage variable to 0
On beforeunload, check if the variable is 0. If so it means that the user is closing and not changing url.
This is still a roundabout way to go, but makes sense to me
As #jAndy mentioned, there is no properly javascript code to detect a window being closed.
I started from what #Syno had proposed.
I had pass though a situation like that and provided you follow these steps, you'll be able to detect it.
I tested it on Chrome 67+ and Firefox 61+.
var wrapper = function () { //ignore this
var closing_window = false;
$(window).on('focus', function () {
closing_window = false;
//if the user interacts with the window, then the window is not being
//closed
});
$(window).on('blur', function () {
closing_window = true;
if (!document.hidden) { //when the window is being minimized
closing_window = false;
}
$(window).on('resize', function (e) { //when the window is being maximized
closing_window = false;
});
$(window).off('resize'); //avoid multiple listening
});
$('html').on('mouseleave', function () {
closing_window = true;
//if the user is leaving html, we have more reasons to believe that he's
//leaving or thinking about closing the window
});
$('html').on('mouseenter', function () {
closing_window = false;
//if the user's mouse its on the page, it means you don't need to logout
//them, didn't it?
});
$(document).on('keydown', function (e) {
if (e.keyCode == 91 || e.keyCode == 18) {
closing_window = false; //shortcuts for ALT+TAB and Window key
}
if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
}
});
// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
closing_window = false;
});
// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
closing_window = false;
});
var toDoWhenClosing = function() {
//write a code here likes a user logout, example:
//$.ajax({
// url: '/MyController/MyLogOutAction',
// async: false,
// data: {
// },
// error: function () {
// },
// success: function (data) {
// },
//});
};
window.onbeforeunload = function () {
if (closing_window) {
toDoWhenClosing();
}
};
};
try this,
I am sure this will work for you.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
$(function() {
try{
opera.setOverrideHistoryNavigationMode('compatible');
history.navigationMode = 'compatible';
}catch(e){}
function ReturnMessage()
{
return "wait";
}
function UnBindWindow()
{
$(window).unbind('beforeunload', ReturnMessage);
}
$(window).bind('beforeunload',ReturnMessage );
});
</script>
Try this. It will work. jquery unload method is depreceted.
window.onbeforeunload = function(event) {
event.returnValue = "Write something clever here..";
};

Detect Close windows event by jQuery

Could you please give me the best way to detect only window close event for all browsers by jQuery?
I mean clicking X button on the browser or window.close(), not meaning F5, form submission,
window.location or link.
I was looking for many threads but have not found the right way yet.
You can use :
$(window).unload(function() {
//do something
});
Unload() is deprecated in jQuery version 1.8, so if you use jQuery > 1.8 you can use even beforeunload instead.
The beforeunload event fires whenever the user leaves your page for any reason.
$(window).on("beforeunload", function() {
return confirm("Do you really want to close?");
});
Source Browser window close event
There is no specific event for capturing browser close event.
You can only capture on unload of the current page.
By this method, it will be effected while refreshing / navigating the current page.
Even calculating of X Y postion of the mouse event doesn't give you good result.
The unload() method was deprecated in jQuery version 1.8.
so if you are using versions older than 1.8
then use -
$(window).unload(function(){
alert("Goodbye!");
});
and if you are using 1.8 and higher
then use -
window.onbeforeunload = function() {
return "Bye now!";
};
hope this will work :-)
There is no specific event for capturing browser close event. But we can detect by the browser positions XY.
<script type="text/javascript">
$(document).ready(function() {
$(document).mousemove(function(e) {
if(e.pageY <= 5)
{
//this condition would occur when the user brings their cursor on address bar
//do something here
}
});
});
</script>
Combine the mousemove and window.onbeforeunload event :-
I used for set TimeOut for Audit Table.
$(document).ready(function () {
var checkCloseX = 0;
$(document).mousemove(function (e) {
if (e.pageY <= 5) {
checkCloseX = 1;
}
else { checkCloseX = 0; }
});
window.onbeforeunload = function (event) {
if (event) {
if (checkCloseX == 1) {
//alert('1111');
$.ajax({
type: "GET",
url: "Account/SetAuditHeaderTimeOut",
dataType: "json",
success: function (result) {
if (result != null) {
}
}
});
}
}
};
});
You can solve this problem with vanilla-Js:
Unload Basics
If you want to prompt or warn your user that they're going to close your page, you need to add code that sets .returnValue on a beforeunload event:
window.addEventListener('beforeunload', (event) => {
event.returnValue = `Are you sure you want to leave?`;
});
There's two things to remember.
Most modern browsers (Chrome 51+, Safari 9.1+ etc) will ignore what you say and just present a generic message. This prevents webpage authors from writing egregious messages, e.g., "Closing this tab will make your computer EXPLODE! đź’Ł".
Showing a prompt isn't guaranteed. Just like playing audio on the web, browsers can ignore your request if a user hasn't interacted with your page. As a user, imagine opening and closing a tab that you never switch to—the background tab should not be able to prompt you that it's closing.
Optionally Show
You can add a simple condition to control whether to prompt your user by checking something within the event handler. This is fairly basic good practice, and could work well if you're just trying to warn a user that they've not finished filling out a single static form. For example:
let formChanged = false;
myForm.addEventListener('change', () => formChanged = true);
window.addEventListener('beforeunload', (event) => {
if (formChanged) {
event.returnValue = 'You have unfinished changes!';
}
});
But if your webpage or webapp is reasonably complex, these kinds of checks can get unwieldy. Sure, you can add more and more checks, but a good abstraction layer can help you and have other benefits—which I'll get to later. 👷‍♀️
Promises
So, let's build an abstraction layer around the Promise object, which represents the future result of work- like a response from a network fetch().
The traditional way folks are taught promises is to think of them as a single operation, perhaps requiring several steps- fetch from the server, update the DOM, save to a database. However, by sharing the Promise, other code can leverage it to watch when it's finished.
Pending Work
Here's an example of keeping track of pending work. By calling addToPendingWork with a Promise—for example, one returned from fetch()—we'll control whether to warn the user that they're going to unload your page.
const pendingOps = new Set();
window.addEventListener('beforeunload', (event) => {
if (pendingOps.size) {
event.returnValue = 'There is pending work. Sure you want to leave?';
}
});
function addToPendingWork(promise) {
pendingOps.add(promise);
const cleanup = () => pendingOps.delete(promise);
promise.then(cleanup).catch(cleanup);
}
Now, all you need to do is call addToPendingWork(p) on a promise, maybe one returned from fetch(). This works well for network operations and such- they naturally return a Promise because you're blocked on something outside the webpage's control.
more detail can view in this url:
https://dev.to/chromiumdev/sure-you-want-to-leavebrowser-beforeunload-event-4eg5
Hope that can solve your problem.

Categories

Resources