beforeunload
is not used to detect when tabs close or windows close is used to detect the "download" of the page, ie this event is also triggered when you click on a link that goes to another page, because the current page will be downloaded to load the new.
Important: There’s no way to detect the difference between "reliable way" whether you’re closing or paging at the event beforeunload
.
What you can do is use page with Ajax and the history.pushState
to change the URL, rather than real words, however the use of beforeunload
with ajax is also problematic when we close tabs and windows, read the following.
Why it is not recommended to use beforeunload
Note one thing very important, do not recommend using beforeunload
to detect that the page has closed, as this cannot be guaranteed, due to the following problems that the ajax request cannot be delivered to the server:
- When closing a tab or window all ajax requests are canceled
- Browser may occur to freeze or close because of an error (crash), then ajax will never be triggered.
- For some reason the computer suddenly shut down, for example a power outage.
API Beacon
Of course there is the API Beacon which is similar to XmlHttpRequest
(alias Ajax) that "guarantees" the delivery of the request even if the page is downloaded (change page, close tab/window), which is different from the XmlHttpRequest
which is canceled if the page starts downloading randomly it is still in the sending process (from 0 to 2 in the value of readyState
usually).
But even though Beacon seems to solve a lot of cases, you have to understand:
- It’s a technology EXPERIMENTAL
- If the browser process dies abruptly, runs out of power and the PC shuts down or is simply without internet signal, this will never be delivered
In such cases Beacon will never deliver the request to the server.
Alternative to beforeunload
As I said in these two links:
I recommend creating a timer (as Google does, as I mentioned in the first link), that is to say nobody uses beforeunload
for he is not a good practice for this specific purpose.
The timer should be created on the server side and will depend on the language you use (in your case is PHP), an example I already mentioned in the link above would be, create a table:
id | login | senha | nome | lastactive
-----------------------------------------------
1 | test | test | João | 2015-06-24 01:00:23
-----------------------------------------------
2 | maria | maria | Maria| 2015-06-24 01:00:33
Assuming I am the ID 1 user (one must use Session) you would have to run this command with each "my" request (using php and mysqli or Pdo):
UPDATE usuarios SET lastactive=CURRENT_TIMESTAMP WHERE id=1
And to check online users:
define('REQUEST_TIME', $_SERVER['REQUEST_TIME']);
define('TIME_ONLINE', 120);//120 = 2 minutos
function isOnline($timer) {
return REQUEST_TIME - strtotime($timer) > TIME_ONLINE;
}
$query = 'SELECT nome, lastactive WHERE 1 ORDER by nome';
if ($result = $mysqli->query($query)) {
while ($row = $result->fetch_assoc()) {
echo 'Usuário ', $row['nome'], ' está ',
(isOnline($row['lastactive']) ? 'online' : 'offline'), '<br>';
}
$result->free();
}
These are just snippets of code to understand the logic. Read the link for more details: Check if user closed browser
What is the use of beforeunload
This event was created to be able to perform functions aimed at interactions with the front-end (or it will hardly work well with ajax due to the factors already mentioned), such as preventing the user to accidentally close a page that needs to be open, as an online game, use example:
window.onbeforeunload = function() {
return "Gostaria mesmo de sair desta página?";
};
When trying to close the window tab or change page will appear an Alert with two buttons and your message:
Documentation:
https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload
Speak William, I created a function the way you put and made a first test, it worked successfully. Thanks for the support!!!!
– RRV