Respostas:
Experimente o onbeforeunloadevento: ele é acionado imediatamente antes do descarregamento da página. Também permite que você pergunte novamente se o usuário realmente deseja sair. Veja a demonstração onbeforeunload Demo .
Como alternativa, você pode enviar uma solicitação do Ajax quando ele sair.
A Mozilla Developer Network tem uma boa descrição e exemplo de onbeforeunload .
Se você deseja avisar o usuário antes de sair da página, se ela estiver suja (ou seja, se o usuário inseriu alguns dados):
window.addEventListener('beforeunload', function(e) {
var myPageIsDirty = ...; //you implement this logic...
if(myPageIsDirty) {
//following two lines will cause the browser to ask the user if they
//want to leave. The text of this dialog is controlled by the browser.
e.preventDefault(); //per the standard
e.returnValue = ''; //required for Chrome
}
//else: user is allowed to leave without a warning dialog
});
Aqui está uma solução alternativa: como na maioria dos navegadores, os controles de navegação (a barra de navegação, as guias etc.) estão localizados acima da área de conteúdo da página, você pode detectar o ponteiro do mouse saindo da página pela parte superior e exibir um " antes de sair " diálogo. É completamente discreto e permite que você interaja com o usuário antes que ele efetue a ação para sair.
$(document).bind("mouseleave", function(e) {
if (e.pageY - $(window).scrollTop() <= 1) {
$('#BeforeYouLeaveDiv').show();
}
});
A desvantagem é que, é claro, é um palpite de que o usuário realmente pretenda sair, mas na grande maioria dos casos está correto.
Para isso eu estou usando:
window.onbeforeunload = function (e) {
}
É acionado imediatamente antes da página ser descarregada.
onbeforeunload?
Sei que esta pergunta foi respondida, mas caso você queira acionar algo apenas quando o NAVEGADOR real é fechado, e não apenas quando ocorre um carregamento de página, você pode usar este código:
window.onbeforeunload = function (e) {
if ((window.event.clientY < 0)) {
//window.localStorage.clear();
//alert("Y coords: " + window.event.clientY)
}
};
No meu exemplo, estou limpando o armazenamento local e alertando o usuário com as conexões do mouse e do mouse; somente quando o navegador estiver fechado, isso será ignorado em todas as cargas de página do programa.
evariável nesse caso) deve ser usado: stackoverflow.com/questions/9813445/ ...
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. developer.mozilla.org/pt-BR/docs/Web/API/Window/event
Uma maneira (ligeiramente hacky) de fazer isso é substituir e os links que saem do seu site com uma chamada AJAX para o lado do servidor, indicando que o usuário está saindo, em seguida, use o mesmo bloco javascript para levar o usuário ao site externo solicitou.
É claro que isso não funcionará se o usuário simplesmente fechar a janela do navegador ou digitar um novo URL.
Para contornar isso, você poderia usar o setTimeout () do Javascript na página, fazendo uma chamada AJAX a cada poucos segundos (dependendo da rapidez com que você deseja saber se o usuário saiu).
Graças ao Service Workers , é possível implementar uma solução semelhante à do Adam puramente no lado do cliente, desde que o navegador a suporte. Apenas evite solicitações de pulsação:
// The delay should be longer than the heartbeat by a significant enough amount that there won't be false positives
const liveTimeoutDelay = 10000
let liveTimeout = null
global.self.addEventListener('fetch', event => {
clearTimeout(liveTimeout)
liveTimeout = setTimeout(() => {
console.log('User left page')
// handle page leave
}, liveTimeoutDelay)
// Forward any events except for hearbeat events
if (event.request.url.endsWith('/heartbeat')) {
event.respondWith(
new global.Response('Still here')
)
}
})
setInterval(() => fetch('/heartbeat'), 5000)?
No caso de você precisar fazer algum código assíncrono (como enviar uma mensagem ao servidor de que o usuário não está focado na sua página no momento), o evento beforeunloadnão dará tempo para que o código assíncrono seja executado. No caso de assíncrono, descobri que os eventos visibilitychangee mouseleavesão as melhores opções. Esses eventos são acionados quando o usuário altera a guia, oculta o navegador ou remove o cursor do escopo da janela.
document.addEventListener('mouseleave', e=>{
//do some async code
})
document.addEventListener('visibilitychange', e=>{
if (document.visibilityState === 'visible') {
//report that user is in focus
} else {
//report that user is out of focus
}
})
Quanto vale a pena, foi isso que fiz e talvez possa ajudar outras pessoas, mesmo que o artigo seja antigo.
PHP:
session_start();
$_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR'];
if(isset($_SESSION['userID'])){
if(!strpos($_SESSION['activeID'], '-')){
$_SESSION['activeID'] = $_SESSION['userID'].'-'.$_SESSION['activeID'];
}
}elseif(!isset($_SESSION['activeID'])){
$_SESSION['activeID'] = time();
}
JS
window.setInterval(function(){
var userid = '<?php echo $_SESSION['activeID']; ?>';
var ipaddress = '<?php echo $_SESSION['ipaddress']; ?>';
var action = 'data';
$.ajax({
url:'activeUser.php',
method:'POST',
data:{action:action,userid:userid,ipaddress:ipaddress},
success:function(response){
//alert(response);
}
});
}, 5000);
Chamada Ajax para activeUser.php
if(isset($_POST['action'])){
if(isset($_POST['userid'])){
$stamp = time();
$activeid = $_POST['userid'];
$ip = $_POST['ipaddress'];
$query = "SELECT stamp FROM activeusers WHERE activeid = '".$activeid."' LIMIT 1";
$results = RUNSIMPLEDB($query);
if($results->num_rows > 0){
$query = "UPDATE activeusers SET stamp = '$stamp' WHERE activeid = '".$activeid."' AND ip = '$ip' LIMIT 1";
RUNSIMPLEDB($query);
}else{
$query = "INSERT INTO activeusers (activeid,stamp,ip)
VALUES ('".$activeid."','$stamp','$ip')";
RUNSIMPLEDB($query);
}
}
}
Base de dados:
CREATE TABLE `activeusers` (
`id` int(11) NOT NULL,
`activeid` varchar(20) NOT NULL,
`stamp` int(11) NOT NULL,
`ip` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Basicamente, a cada 5 segundos, os js postam em um arquivo php que rastreia o usuário e o endereço IP dos usuários. Usuários ativos são simplesmente um registro de banco de dados que possui uma atualização para o registro de data e hora do banco de dados em 5 segundos. Usuários antigos param de atualizar para o banco de dados. O endereço IP é usado apenas para garantir que um usuário seja único, para que 2 pessoas no site ao mesmo tempo não se registrem como 1 usuário.
Provavelmente não é a solução mais eficiente, mas faz o trabalho.