Executar o código JavaScript ao fechar a janela ou atualizar a página?

110

Existe uma maneira de executar um código JavaScript final quando um usuário fecha uma janela do navegador ou atualiza a página?

Estou pensando em algo semelhante a onload, mas mais parecido com onclose? Obrigado.

Eu não gosto do método onbeforeunload, que sempre resulta em uma caixa de confirmação aparecendo (sair da página / permanecer no Mozilla) ou (recarregar / não recarregar no Chrome). Existe uma maneira de executar o código silenciosamente?

Peter
fonte
1
Possível duplicata: stackoverflow.com/questions/805463/…
1,44 MB
18
Espere - na verdade NÃO É uma duplicata ... Ele quer saber como executar algo SEM um prompt para o usuário - as perguntas vinculadas fazem o contrário ...
Phildo

Respostas:

86

Existem ambos window.onbeforeunloade window.onunload, que são usados ​​de maneiras diferentes dependendo do navegador. Você pode avaliá-los definindo as propriedades da janela para funções ou usando .addEventListener:

window.onbeforeunload = function(){
   // Do something
}
// OR
window.addEventListener("beforeunload", function(e){
   // Do something
}, false);

Normalmente, onbeforeunloadé usado se você precisar impedir o usuário de sair da página (por exemplo, o usuário está trabalhando em alguns dados não salvos, então ele deve salvar antes de sair). onunloadnão é compatível com o Opera , até onde eu sei, mas você sempre pode definir ambos.

JCOC611
fonte
Isso funcionou para mim: Firefox (69.0.2) e Chrome (77.0.3865.90)
FelipeCaparelli
51

Ok, encontrei uma solução que funciona para isso, consiste em usar o beforeunloadevento e depois fazer o handler retornar null. Isso executa o código desejado sem que uma caixa de confirmação apareça. É mais ou menos assim:

window.onbeforeunload = closingCode;
function closingCode(){
   // do something...
   return null;
}

Espero que isto ajude.

Peter
fonte
10
Não é disparado também na navegação de saída e na atualização (F5)? Se for assim, ele realmente não resolve a questão ...
Jago
1
Não testei, mas acho que return false;faz o mesmo (ou seja, impede o comportamento padrão) e é semanticamente mais correto.
collimarco
1
return false ainda irá abrir a caixa de diálogo perguntando se você deseja sair da página ou não. Eu testei em uma âncora. Com return null, a caixa de diálogo não apareceu, mas ainda apareceu o console.log
Ricky Stam
20

Às vezes, você pode querer que o servidor saiba que o usuário está saindo da página. Isso é útil, por exemplo, para limpar imagens não salvas armazenadas temporariamente no servidor, para marcar esse usuário como "offline" ou para registrar quando ele termina sua sessão.

Historicamente, você enviaria uma solicitação AJAX na beforeunloadfunção, mas isso tem dois problemas. Se você enviar uma solicitação assíncrona, não há garantia de que a solicitação será executada corretamente. Se você enviar uma solicitação síncrona, é mais confiável, mas o navegador travará até que a solicitação seja concluída. Se esta for uma solicitação lenta, isso seria um grande inconveniente para o usuário.

Felizmente, agora temos navigator.sendBeacon(). Com a utilização do sendBeacon()método, os dados são transmitidos de forma assíncrona ao servidor web quando o Agente do Usuário tem a oportunidade de fazê-lo, sem atrasar o descarregamento ou afetar o desempenho da próxima navegação. Isso resolve todos os problemas com o envio de dados analíticos: os dados são enviados de maneira confiável, são enviados de forma assíncrona e não afetam o carregamento da próxima página. Aqui está um exemplo de seu uso:

window.addEventListener("unload", logData, false);

function logData() {
  navigator.sendBeacon("/log.php", analyticsData);
}

sendBeacon()é compatível com:

  • Edge 14
  • Firefox 31
  • Chrome 39
  • Safari 11.1
  • Opera 26
  • iOS Safari 11.4

Atualmente NÃO é compatível com:

  • Internet Explorer
  • Opera Mini

Aqui está um polyfill para sendBeacon () caso você precise adicionar suporte para navegadores não suportados. Se o método não estiver disponível no navegador, ele enviará uma solicitação AJAX síncrona.

Mike
fonte
Esta questão estava no escopo de um caso "Para enviar uma solicitação ao servidor". A ideia era ser capaz de manter as guias abertas por usuário e limpar no back-end quando uma guia é fechada.
Peter
@Peter Eu estava incluindo para completar, mas excluí.
Mike
@ Mike, por favor, NÃO exclua sua resposta. Ele não apenas completa a melhor resposta selecionada (deve ser a sua), mas também apresenta o evento usado para capturar a saída ou o fechamento da janela
Alex8752
@ Alex8752 Não eliminei a minha resposta, editei uma parte que era irrelevante para a pergunta, que pode ver aqui .
Mike
1
@AshokKumar Você controla o que envia para o servidor. Se você deseja enviar coisas por GET, não há nada que o impeça de enviar sua solicitação para algo como http://example.com/script.php?token=something&var1=val1&var2=val2colocar esses valores em GET.
Mike
14

versão jQuery:

$(window).unload(function(){
    // Do Something
});

Atualização : jQuery 3:

$(window).on("unload", function(e) {
    // Do Something
});

Obrigado garrett

Paras
fonte
8

A documentação aqui encoraja ouvir o evento onbeforeunload e / ou adicionar um ouvinte de evento na janela.

window.addEventListener('beforeunload', function(event) {
  //do something here
}, false);

Você também pode simplesmente preencher as propriedades .onunload ou .onbeforeunload da janela com uma função ou uma referência de função.

Embora o comportamento não seja padronizado nos navegadores, a função pode retornar um valor que o navegador exibirá ao confirmar se deve ou não sair da página.

Davejoem
fonte
7

Você pode usar window.onbeforeunload.

window.onbeforeunload = confirmExit;
function confirmExit(){
    alert("confirm exit is being called");
    return false;
}
Gurpreet Singh
fonte
3

O evento é chamado beforeunload, então você pode atribuir uma função a window.onbeforeunload.

Phssthpok
fonte
-2

Você pode tentar algo assim:

<SCRIPT language="JavaScript">
<!--
function loadOut()
{
window.location="http://www.google.com";
}
//-->
</SCRIPT>

<body onBeforeUnload="loadOut()">
Dane Balia
fonte
23
Cuidado, as pessoas que lêem isso não eram em tempos antigos - isso é JS e HTML antigos e as outras sugestões aqui são muito melhores.
RAnders00