Save state using HTML5 Web SQL on window unload - javascript

I'm using the Web SQL API to store some information on a page; I'd like to save the state of the page when the user closes the page or navigates away, thus, I start with:
window.onunload = function () {
db.transaction(function (tx) {
executeSql("INSERT INTO State (foo) VALUES (?)", [foo]);
});
};
However, this is asynchronous so it doesn't complete before the page goes away.
I solve this unsatisfactorily by adding a (disingenuous, since it hasn't happened yet) alert("Saved!"); at the end of my window.onunload, which delays the unload until the DB has a chance to do its thing, but I'd rather not have that alert if I can avoid it.
Any ideas? I need to sort of block the thread calling the onunload function for a moment, which is what the alert does.
(BTW, to head off any suggestion that I use the synchronous openDatabaseSync version, that API is speced and implemented only for Web Workers, not for the Window object.)

Do you have access to WebSockets?
Could you listen on a socket, and then when it's time to unload you connect to that listening socket, synchronously. When the listener receives a connection, it starts the insert and closes the connection after the query is done.
This is the only thing I could think of, and I am not sure that these interfaces support this kind of usage. I approached this by thinking how I would do this if I had a server: I would use a synchronous network connection to the server to write the state.
Also, I am not sure that the unload event can be blocked for an indeterminate length of time, but some Googling for "unload synchronous ajax" suggests it could be.
Update 7/19 10:26pm PDT
Browser WebSockets are send-only, you can't open a socket for listening.

I'll just mention for posterity that another idea I've come across is to open a modal dialog with a timeout, like this:
window.showModalDialog('javascript:document.writeln ("<script>window.setTimeout(function () { window.close(); }, 100);</script>")');
But that's not completely cross-platform, perhaps. And the dialog window is visible in some browsers (Safari at least).

There is reportedly a way of making SQL calls synchronous.
Synchronous Web SQL is part of the Web SQL specification draft.
However this part is the one that was not implemented in any browser yet.
And the specification draft is not going anywhere, because there is just one DB - SQLite.
However the fair folks in appcelerator somehow did the trick. Damn if I know how they did it though. If you can figure it out, please update this thread.

Related

Fetch API before the user closes the browser is not behaving consistently [duplicate]

I'm trying to find out when a user left a specified page. There is no problem finding out when he used a link inside the page to navigate away but I kind of need to mark up something like when he closed the window or typed another URL and pressed enter. The second one is not so important but the first one is. So here is the question:
How can I see when a user closed my page (capture window.close event), and then... doesn't really matter (I need to send an AJAX request, but if I can get it to run an alert, I can do the rest).
Updated 2021
TL;DR
Beacon API is the solution to this issue (on almost every browser).
A beacon request is supposed to complete even if the user exits the page.
When should you trigger your Beacon request ?
This will depend on your usecase. If you are looking to catch any user exit, visibilitychange (not unload) is the last event reliably observable by developers in modern browsers.
NB: As long as implementation of visibilitychange is not consistent across browsers, you can detect it via the lifecycle.js library.
# lifecycle.js (1K) for cross-browser compatibility
# https://github.com/GoogleChromeLabs/page-lifecycle
<script defer src="/path/to/lifecycle.js"></script>
<script defer>
lifecycle.addEventListener('statechange', function(event) {
if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {
var url = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(url, data);
}
});
</script>
Details
Beacon requests are supposed to run to completion even if the user leaves the page - switches to another app, etc - without blocking user workflow.
Under the hood, it sends a POST request along with the user credentials (cookies), subject to CORS restrictions.
var url = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(url, data);
The question is when to send your Beacon request. Especially if you want to wait until the last moment to send session info, app state, analytics, etc.
It used to be common practice to send it during the unload event, but changes to page lifecycle management - driven by mobile UX - killed this approach. Today, most mobile workflows (switching to new tab, switching to the homescreen, switching to another app...) do not trigger the unload event.
If you want to do things when a user exits your app/page, it is now recommended to use the visibilitychange event and check for transitioning from passive to hidden state.
document.addEventListener('visibilitychange', function() {
if (document.visibilityState == 'hidden') {
// send beacon request
}
});
The transition to hidden is often the last state change that's reliably observable by developers (this is especially true on mobile, as users can close tabs or the browser app itself, and the beforeunload, pagehide, and unload events are not fired in those cases).
This means you should treat the hidden state as the likely end to the user's session. In other words, persist any unsaved application state and send any unsent analytics data.
Details of the Page lifecyle API are explained in this article.
However, implementation of the visibilitychange event, as well as the Page lifecycle API is not consistent across browsers.
Until browser implementation catches up, using the lifecycle.js library and page lifecycle best practices seems like a good solution.
# lifecycle.js (1K) for cross-browser compatibility
# https://github.com/GoogleChromeLabs/page-lifecycle
<script defer src="/path/to/lifecycle.js"></script>
<script defer>
lifecycle.addEventListener('statechange', function(event) {
if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {
var url = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(url, data);
}
});
</script>
For more numbers about the reliability of vanilla page lifecycle events (without lifecycle.js), there is also this study.
Adblockers
Adblockers seem to have options that block sendBeacon requests.
Cross site requests
Beacon requests are POST requests that include cookies and are subject to CORS spec. More info.
There are unload and beforeunload javascript events, but these are not reliable for an Ajax request (it is not guaranteed that a request initiated in one of these events will reach the server).
Therefore, doing this is highly not recommended, and you should look for an alternative.
If you definitely need this, consider a "ping"-style solution. Send a request every minute basically telling the server "I'm still here". Then, if the server doesn't receive such a request for more than two minutes (you have to take into account latencies etc.), you consider the client offline.
Another solution would be to use unload or beforeunload to do a Sjax request (Synchronous JavaScript And XML), but this is completely not recommended. Doing this will basically freeze the user's browser until the request is complete, which they will not like (even if the request takes little time).
1) If you're looking for a way to work in all browsers, then the safest way is to send a synchronous AJAX to the server. It is is not a good method, but at least make sure that you are not sending too much of data to the server, and the server is fast.
2) You can also use an asynchronous AJAX request, and use ignore_user_abort function on the server (if you're using PHP). However ignore_user_abort depends a lot on server configuration. Make sure you test it well.
3) For modern browsers you should not send an AJAX request. You should use the new navigator.sendBeacon method to send data to the server asynchronously, and without blocking the loading of the next page. Since you're wanting to send data to server before user moves out of the page, you can use this method in a unload event handler.
$(window).on('unload', function() {
var fd = new FormData();
fd.append('ajax_data', 22);
navigator.sendBeacon('ajax.php', fd);
});
There also seems to be a polyfill for sendBeacon. It resorts to sending a synchronous AJAX if method is not natively available.
IMPORTANT FOR MOBILE DEVICES : Please note that unload event handler is not guaranteed to be fired for mobiles. But the visibilitychange event is guaranteed to be fired. So for mobile devices, your data collection code may need a bit of tweaking.
You may refer to my blog article for the code implementation of all the 3 ways.
I also wanted to achieve the same functionality & came across this answer from Felix(it is not guaranteed that a request initiated in one of these events will reach the server).
To make the request reach to the server we tried below code:-
onbeforeunload = function() {
//Your code goes here.
return "";
}
We are using IE browser & now when user closes the browser then he gets the confirmation dialogue because of return ""; & waits for user's confirmation & this waiting time makes the request to reach the server.
Years after posting the question I made a way better implementation including nodejs and socket.io (https://socket.io) (you can use any kind of socket for that matter but that was my personal choice).
Basically I open up a connection with the client, and when it hangs up I just save data / do whatever I need. Obviously this cannot be use to show anything / redirect the client (since you are doing it server side), but is what I actually needed back then.
io.on('connection', function(socket){
socket.on('disconnect', function(){
// Do stuff here
});
});
So... nowadays I think this would be a better (although harder to implement because you need node, socket, etc., but is not that hard; should take like 30 min or so if you do it first time) approach than the unload version.
The selected answer is correct that you can't guarantee that the browser sends the xhr request, but depending on the browser, you can reliably send a request on tab or window close.
Normally, the browser closes before xhr.send() actually executes. Chrome and edge look like they wait for the javascript event loop to empty before closing the window. They also fire the xhr request in a different thread than the javascript event loop. This means that if you can keep the event loop full for long enough, the xhr will successfully fire. For example, I tested sending an xhr request, then counting to 100,000,000. This worked very consistently in both chrome and edge for me. If you're using angularjs, wrapping your call to $http in $apply accomplishes the same thing.
IE seems to be a little different. I don't think IE waits for the event loop to empty, or even for the current stack frame to empty. While it will occasionally correctly send a request, what seems to happen far more often (80%-90% of the time) is that IE will close the window or tab before the xhr request has completely executed, which result in only a partial message being sent. Basically the server receives a post request, but there's no body.
For posterity, here's the code I used attached as the window.onbeforeunload listener function:
var xhr = new XMLHttpRequest();
xhr.open("POST", <your url here>);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
var payload = {id: "123456789"};
xhr.send(JSON.stringify(payload));
for(var i = 0; i < 100000000; i++) {}
I tested in:
Chrome 61.0.3163.100
IE 11.608.15063.0CO
Edge 40.15063.0.0
Try this one. I solved this problem in javascript, sending ajax call to server on browse or tab closing. I had a problem with refreshing page because on onbeforeunload function including refreshing of the page. performance.navigation.type == 1 should isolate refresh from closing (on mozzila browser).
$(window).bind('mouseover', (function () { // detecting DOM elements
window.onbeforeunload = null;
}));
$(window).bind('mouseout', (function () { //Detecting event out of DOM
window.onbeforeunload = ConfirmLeave;
}));
function ConfirmLeave() {
if (performance.navigation.type == 1) { //detecting refresh page(doesnt work on every browser)
}
else {
logOutUser();
}
}
$(document).bind('keydown', function (e) { //detecting alt+F4 closing
if (e.altKey && e.keyCode == 115) {
logOutUser();
}
});
function logOutUser() {
$.ajax({
type: "POST",
url: GWA("LogIn/ForcedClosing"), //example controller/method
async: false
});
}
Im agree with Felix idea and I have solved my problem with that solution and now I wanna to clear the Server Side solution:
1.send a request from client side to server
2.save time of the last request recived in a variable
3.check the server time and compare it by the variable of last recived
request
4.if the result is more than the time you expect,start running the
code you want to run when windows closed...
Use:
<body onUnload="javascript:">
It should capture everything except shutting down the browser program.

Angular 6: Trying to make synchronous call (delete) on browser close event (beforeunload/unload event of browser)

Actually, I want to update a flag in Db using a service call(Delete method) once the user close the browser. I am able to detect browser close action using onbeforeunload and onunload events but async call doesn't work for me(sometimes in debugging mode it works fine but on higher env it doesn't work).
Then, I tried to make sync request but then I found that Chrome now disallows synchronous XHR during page dismissal when the page is being navigated away from or closed by the user.
check link : https://www.chromestatus.com/feature/4664843055398912
I have tried new XMLHttpRequest() as sync, fetch api also Navigator.sendBeacon() but unfortunately nothing works for me.
Please suggest something which works because I have visited so many posts but nothing works for me.
Thanks in advance.
I have some solution for this. Hope so any one of them solves your issue.
constructor() {
window.onbeforeunload = ()=>{
//call API here
}
}
In your component constructor write above code
OR
In my opinion the better idea is making the heartbeat api that sends requests every N seconds to notify server that the session is active and the user is online. On the server check every M minutes if there was no heartbeat requests for more than N seconds: if it is so - execute the API request(what you wanted to execute on crash).
OR
'beforeunload' would be trigger when refreshing pages, closing tab, or closing the browser.
#HostListener('window:beforeunload', ['$event'])
beforeUnload(e: Event) {
e.returnValue = false;
}
OR
It is not possible to ensure that every time an user exits a browser page a specific function will be triggered. The reason is that the browser could close the window for many reasons. Yes it could be a user action but this is not the only case. For example The browser could crash.
In my case I will have to find another strategy to track the time the user stays on the page. For example I am planning to send a lot of API calls before the user exits with all the informations I need to understand his stay on the page. I will update the answer when I will reach a good solution. Anyway I will still wait for better answers.
You can use the fetch API.
The syntax would be:
fetch('API', {
method: 'POST', // Other opn are also supported like GET,PUT DELETE
body: '',
keepalive: true
});
Just an additional read:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Notifications in javascript without user input

I've been trying to figure out a way to use notifications on a background process and couldnt find anything online about it. So, I figured out one way around it and wanted to share (Not sure if this is the best way to go about doing this but here goes:)
Problem: I want to notify the user of new info when the page is running but in the background (blurred). I could use alert('new info!'); to get the taskbar icon to flash, but then you have to manually dismiss it (tried it and it's hella annoying). I really liked the notifications, but they only work if the user performs an action, so not helpful...
I hope I won't be telling something stupid, but from where I see it (and remember from school) that's basically how http works : a request is sent to the server, which issues a response eventually after executing some server-side code.
Basically you're asking for a "PUSH" functionality from server to client, and in that case you can't make use of HTTP.
Some tricks exist to work around this limitation, but basically they're all issuing requests at a certain frequency (Dave's answer does exactly that). If your site doesn't change that much, that means a lot of requests are issued for no reason (nothing has changed), consuming bandwith for nothing.
From what I know, the answer to this is called Websockets, which are supported by recent browsers only. I never had the chance to use it though so I couldn't tell much more about it. This allows full duplex communication, thus allowing server to "push" data to the client. I guess that's what SO uses for "new message" notifications (top left of the screen - you see immediately when you receive a new message)
My solution: I made a chrome extension that runs in the background and triggers the notifications. It's a little limited in scope as you need to have chrome to do it, but it does what i need it to, and for the purposes of the problem i'm working on, i can just make my user group use chrome ;D
The specifics: The extension only has two components, the manifest and a script. Currently, i setup the manifest so that it only works on my site using the match identifier... and i set the permissions to include notifications.
The JS script has a window.setinterval that looks for an element in the page with the id NOTIFIER. If it's empty, it does nothing, otherwise it creates a notification based on the content and then clears the content to prevent showing the same notification multiple times... (I tried using .onchange for that element, but couldn't get the event to trigger... I'd prefer to do this on an event rather then setInterval)
Notify.js
function onExtLoad() {
var timer = setInterval(refresh,1000);
}
document.addEventListener('DOMContentLoaded', onExtLoad());
function refresh() {
if (document.getElementById('NOTIFIER').innerHTML == "") {
//do nothing?
} else {
var notification = webkitNotifications.createNotification("",
"You got a new message",
document.getElementById('NOTIFIER').innerHTML);
notification.show();
document.getElementById('NOTIFIER').innerHTML = "";
}
}
Then, all i need to do is have the JS on the page control when it adds info the the NOTIFIER and voila! notifications!
Hope this helps someone else.
#ExpertSystem: I messed around with the MutationObserver but I can only get it to trigger once. Here's a JSFiddle: http://jsfiddle.net/BTX8x/1/
Am I missing something? Is there a way to reset it?
EDIT: Figured it out, i needed subtree:true

How would you create an auto-updating newsfeed without a reload?

How would I go around creating an auto-updating newsfeed? I was going to use NodeJS, but someone told me that wouldn't work when I got into the thousands of users. Right now, I have it so that you can post text to the newsfeed, and it will save into a mysql database. Then, whenever you load the page, it will display all the posts from that database. The problem with this is that you have to reload the page everytime there is an update. I was going to use this to tell the nodejs server someone posted an update...
index.html
function sendPost(name,cont) {
socket.emit("newPost", name, cont);
}
app.js
socket.on("newPost", function (name,cont) {
/* Adding the post to a database
* Then calling an event to say a new post was created
* and emit a new signal with the new data */
});
But that won't work for a ton of people. Does anyone have any suggestions for where I should start, the api's and/or programs I would need to use?
You're on the right track. Build a route on your Node webserver that will cause it to fetch a newspost and broadcast to all connected clients. Then, just fire the request to Node.
On the Node-to-client front, you'll need to learn how to do long polling. It's rather easy - you let a client connect and do not end the response until a message goes through to it. You handle this through event handlers (Postal.JS is worth picking up for this).
The AJAX part is straightforward. $.get("your/node/url").then(function(d) { }); works out of the box. When it comes back (either success or failure), relaunch it. Set its timeout to 60 seconds or so, and end the response on the node front the moment one event targetted it.
This is how most sites do it. The problem with websockets is that, right now, they're a bit of a black sheep due to old IE versions not supporting them. Consider long polling instead if you can afford it.
(Psst. Whoever told you that Node wouldn't work in the thousands of users is talking through their asses. If anything, Node is more adapted to large concurrency than PHP due to the fact that a connection on Node takes almost nothing to keep alive due to the event-driven nature of Node. Don't listen to naysayers.)

JavaScript, browsers, window close - send an AJAX request or run a script on window closing

I'm trying to find out when a user left a specified page. There is no problem finding out when he used a link inside the page to navigate away but I kind of need to mark up something like when he closed the window or typed another URL and pressed enter. The second one is not so important but the first one is. So here is the question:
How can I see when a user closed my page (capture window.close event), and then... doesn't really matter (I need to send an AJAX request, but if I can get it to run an alert, I can do the rest).
Updated 2021
TL;DR
Beacon API is the solution to this issue (on almost every browser).
A beacon request is supposed to complete even if the user exits the page.
When should you trigger your Beacon request ?
This will depend on your usecase. If you are looking to catch any user exit, visibilitychange (not unload) is the last event reliably observable by developers in modern browsers.
NB: As long as implementation of visibilitychange is not consistent across browsers, you can detect it via the lifecycle.js library.
# lifecycle.js (1K) for cross-browser compatibility
# https://github.com/GoogleChromeLabs/page-lifecycle
<script defer src="/path/to/lifecycle.js"></script>
<script defer>
lifecycle.addEventListener('statechange', function(event) {
if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {
var url = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(url, data);
}
});
</script>
Details
Beacon requests are supposed to run to completion even if the user leaves the page - switches to another app, etc - without blocking user workflow.
Under the hood, it sends a POST request along with the user credentials (cookies), subject to CORS restrictions.
var url = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(url, data);
The question is when to send your Beacon request. Especially if you want to wait until the last moment to send session info, app state, analytics, etc.
It used to be common practice to send it during the unload event, but changes to page lifecycle management - driven by mobile UX - killed this approach. Today, most mobile workflows (switching to new tab, switching to the homescreen, switching to another app...) do not trigger the unload event.
If you want to do things when a user exits your app/page, it is now recommended to use the visibilitychange event and check for transitioning from passive to hidden state.
document.addEventListener('visibilitychange', function() {
if (document.visibilityState == 'hidden') {
// send beacon request
}
});
The transition to hidden is often the last state change that's reliably observable by developers (this is especially true on mobile, as users can close tabs or the browser app itself, and the beforeunload, pagehide, and unload events are not fired in those cases).
This means you should treat the hidden state as the likely end to the user's session. In other words, persist any unsaved application state and send any unsent analytics data.
Details of the Page lifecyle API are explained in this article.
However, implementation of the visibilitychange event, as well as the Page lifecycle API is not consistent across browsers.
Until browser implementation catches up, using the lifecycle.js library and page lifecycle best practices seems like a good solution.
# lifecycle.js (1K) for cross-browser compatibility
# https://github.com/GoogleChromeLabs/page-lifecycle
<script defer src="/path/to/lifecycle.js"></script>
<script defer>
lifecycle.addEventListener('statechange', function(event) {
if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {
var url = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(url, data);
}
});
</script>
For more numbers about the reliability of vanilla page lifecycle events (without lifecycle.js), there is also this study.
Adblockers
Adblockers seem to have options that block sendBeacon requests.
Cross site requests
Beacon requests are POST requests that include cookies and are subject to CORS spec. More info.
There are unload and beforeunload javascript events, but these are not reliable for an Ajax request (it is not guaranteed that a request initiated in one of these events will reach the server).
Therefore, doing this is highly not recommended, and you should look for an alternative.
If you definitely need this, consider a "ping"-style solution. Send a request every minute basically telling the server "I'm still here". Then, if the server doesn't receive such a request for more than two minutes (you have to take into account latencies etc.), you consider the client offline.
Another solution would be to use unload or beforeunload to do a Sjax request (Synchronous JavaScript And XML), but this is completely not recommended. Doing this will basically freeze the user's browser until the request is complete, which they will not like (even if the request takes little time).
1) If you're looking for a way to work in all browsers, then the safest way is to send a synchronous AJAX to the server. It is is not a good method, but at least make sure that you are not sending too much of data to the server, and the server is fast.
2) You can also use an asynchronous AJAX request, and use ignore_user_abort function on the server (if you're using PHP). However ignore_user_abort depends a lot on server configuration. Make sure you test it well.
3) For modern browsers you should not send an AJAX request. You should use the new navigator.sendBeacon method to send data to the server asynchronously, and without blocking the loading of the next page. Since you're wanting to send data to server before user moves out of the page, you can use this method in a unload event handler.
$(window).on('unload', function() {
var fd = new FormData();
fd.append('ajax_data', 22);
navigator.sendBeacon('ajax.php', fd);
});
There also seems to be a polyfill for sendBeacon. It resorts to sending a synchronous AJAX if method is not natively available.
IMPORTANT FOR MOBILE DEVICES : Please note that unload event handler is not guaranteed to be fired for mobiles. But the visibilitychange event is guaranteed to be fired. So for mobile devices, your data collection code may need a bit of tweaking.
You may refer to my blog article for the code implementation of all the 3 ways.
I also wanted to achieve the same functionality & came across this answer from Felix(it is not guaranteed that a request initiated in one of these events will reach the server).
To make the request reach to the server we tried below code:-
onbeforeunload = function() {
//Your code goes here.
return "";
}
We are using IE browser & now when user closes the browser then he gets the confirmation dialogue because of return ""; & waits for user's confirmation & this waiting time makes the request to reach the server.
Years after posting the question I made a way better implementation including nodejs and socket.io (https://socket.io) (you can use any kind of socket for that matter but that was my personal choice).
Basically I open up a connection with the client, and when it hangs up I just save data / do whatever I need. Obviously this cannot be use to show anything / redirect the client (since you are doing it server side), but is what I actually needed back then.
io.on('connection', function(socket){
socket.on('disconnect', function(){
// Do stuff here
});
});
So... nowadays I think this would be a better (although harder to implement because you need node, socket, etc., but is not that hard; should take like 30 min or so if you do it first time) approach than the unload version.
The selected answer is correct that you can't guarantee that the browser sends the xhr request, but depending on the browser, you can reliably send a request on tab or window close.
Normally, the browser closes before xhr.send() actually executes. Chrome and edge look like they wait for the javascript event loop to empty before closing the window. They also fire the xhr request in a different thread than the javascript event loop. This means that if you can keep the event loop full for long enough, the xhr will successfully fire. For example, I tested sending an xhr request, then counting to 100,000,000. This worked very consistently in both chrome and edge for me. If you're using angularjs, wrapping your call to $http in $apply accomplishes the same thing.
IE seems to be a little different. I don't think IE waits for the event loop to empty, or even for the current stack frame to empty. While it will occasionally correctly send a request, what seems to happen far more often (80%-90% of the time) is that IE will close the window or tab before the xhr request has completely executed, which result in only a partial message being sent. Basically the server receives a post request, but there's no body.
For posterity, here's the code I used attached as the window.onbeforeunload listener function:
var xhr = new XMLHttpRequest();
xhr.open("POST", <your url here>);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
var payload = {id: "123456789"};
xhr.send(JSON.stringify(payload));
for(var i = 0; i < 100000000; i++) {}
I tested in:
Chrome 61.0.3163.100
IE 11.608.15063.0CO
Edge 40.15063.0.0
Try this one. I solved this problem in javascript, sending ajax call to server on browse or tab closing. I had a problem with refreshing page because on onbeforeunload function including refreshing of the page. performance.navigation.type == 1 should isolate refresh from closing (on mozzila browser).
$(window).bind('mouseover', (function () { // detecting DOM elements
window.onbeforeunload = null;
}));
$(window).bind('mouseout', (function () { //Detecting event out of DOM
window.onbeforeunload = ConfirmLeave;
}));
function ConfirmLeave() {
if (performance.navigation.type == 1) { //detecting refresh page(doesnt work on every browser)
}
else {
logOutUser();
}
}
$(document).bind('keydown', function (e) { //detecting alt+F4 closing
if (e.altKey && e.keyCode == 115) {
logOutUser();
}
});
function logOutUser() {
$.ajax({
type: "POST",
url: GWA("LogIn/ForcedClosing"), //example controller/method
async: false
});
}
Im agree with Felix idea and I have solved my problem with that solution and now I wanna to clear the Server Side solution:
1.send a request from client side to server
2.save time of the last request recived in a variable
3.check the server time and compare it by the variable of last recived
request
4.if the result is more than the time you expect,start running the
code you want to run when windows closed...
Use:
<body onUnload="javascript:">
It should capture everything except shutting down the browser program.

Categories