Uruchomić kod JavaScript przy zamykaniu okna lub odświeżaniu strony?

110

Czy istnieje sposób na uruchomienie końcowego kodu JavaScript, gdy użytkownik zamknie okno przeglądarki lub odświeży stronę?

Myślę o czymś podobnym do onload, ale bardziej jak onclose? Dzięki.

Nie podoba mi się metoda onbeforeunload, która zawsze powoduje wyskakujące okienko z potwierdzeniem (zostaw stronę / zostań na mozilli) lub (przeładuj / nie ładuj ponownie na chrome). Czy istnieje sposób na ciche wykonanie kodu?

Piotr
źródło
1
Możliwy duplikat: stackoverflow.com/questions/805463/…
1.44mb
18
Czekaj - to właściwie NIE JEST duplikatem ... Chce wiedzieć, jak wykonać coś BEZ zachęty dla użytkownika - powiązane pytania zadają coś przeciwnego ...
Phildo

Odpowiedzi:

86

Istnieją obie opcje window.onbeforeunloadi window.onunload, które są używane w różny sposób w zależności od przeglądarki. Możesz je przypisać, ustawiając właściwości okna na funkcje lub używając .addEventListener:

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

Zwykle onbeforeunloadjest używane, jeśli chcesz uniemożliwić użytkownikowi opuszczenie strony (np. Użytkownik pracuje nad niektórymi niezapisanymi danymi, więc powinien zapisać je przed opuszczeniem). onunloadnie jest obsługiwany przez Operę , o ile wiem, ale zawsze możesz ustawić oba.

JCOC611
źródło
To zadziałało dla mnie: Firefox (69.0.2) i Chrome (77.0.3865.90)
FelipeCaparelli
51

Ok, znalazłem działające rozwiązanie na to, polega na użyciu beforeunloadzdarzenia, a następnie wykonaniu powrotu handlera null. Spowoduje to wykonanie żądanego kodu bez wyskakującego okna potwierdzenia. To wygląda mniej więcej tak:

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

Mam nadzieję że to pomoże.

Piotr
źródło
10
Czy to nie jest uruchamiane również podczas nawigacji poza i podczas odświeżania (F5)? Jeśli tak, to tak naprawdę nie odpowiada na pytanie ...
Jago
1
Nie testowane, ale myślę, że return false;robi to samo (tj. Zapobiega domyślnemu zachowaniu) i jest bardziej poprawne semantycznie.
collimarco,
1
return false nadal wyskakuje okno dialogowe z pytaniem, czy chcesz opuścić stronę, czy nie. Przetestowałem to na kotwicy. Z return null okno dialogowe nie wyskoczyło, ale nadal wyświetlało się console.log
Ricky Stam
20

Czasami możesz chcieć powiadomić serwer, że użytkownik opuszcza stronę. Jest to przydatne, na przykład, do czyszczenia niezapisanych obrazów przechowywanych tymczasowo na serwerze, do oznaczania tego użytkownika jako „offline” lub do rejestrowania, kiedy zakończy sesję.

W przeszłości w beforeunloadfunkcji wysyłano żądanie AJAX , jednak wiąże się to z dwoma problemami. Jeśli wyślesz żądanie asynchroniczne, nie ma gwarancji, że zostanie ono wykonane poprawnie. Jeśli wyślesz żądanie synchroniczne, jest ono bardziej niezawodne, ale przeglądarka zawiesiłaby się do zakończenia żądania. Jeśli jest to powolne żądanie, stanowiłoby to ogromną niedogodność dla użytkownika.

Na szczęście teraz mamy navigator.sendBeacon(). Korzystając z tej sendBeacon()metody, dane są przesyłane asynchronicznie do serwera internetowego, gdy Agent użytkownika ma taką możliwość, bez opóźniania rozładunku lub wpływu na wydajność następnej nawigacji. To rozwiązuje wszystkie problemy związane z przesyłaniem danych analitycznych: dane są przesyłane niezawodnie, są wysyłane asynchronicznie i nie ma to wpływu na ładowanie następnej strony. Oto przykład jego użycia:

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

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

sendBeacon()jest obsługiwany w:

  • Krawędź 14
  • Firefox 31
  • Chrome 39
  • Safari 11.1
  • Opera 26
  • iOS Safari 11.4

Obecnie NIE jest obsługiwane w:

  • Internet Explorer
  • Opera Mini

Oto polyfill dla sendBeacon () na wypadek, gdybyś potrzebował dodać obsługę nieobsługiwanych przeglądarek. Jeśli metoda nie jest dostępna w przeglądarce, zamiast tego wyśle ​​synchroniczne żądanie AJAX.

Mikrofon
źródło
To pytanie było w ramach sprawy „Aby wysłać żądanie do serwera”. Pomysł polegał na tym, aby móc zachować zakładki otwartych kart na użytkownika i czyścić zaplecze, gdy karta jest zamknięta.
Peter
@Peter Załączałem to dla kompletności, ale usunąłem.
Mike
@Mike, proszę, NIE usuwaj swojej odpowiedzi. Nie tylko uzupełnia wybraną najlepszą odpowiedź (powinna być twoja), ale także przedstawia zdarzenie użyte do złapania wyjścia lub zamknięcia okna
Alex8752
@ Alex8752 Nie usunąłem swojej odpowiedzi, usunąłem jej część, która nie miała związku z pytaniem, które możesz wyświetlić tutaj .
Mike,
1
@AshokKumar Masz kontrolę nad tym, co wysyłasz na serwer. Jeśli chcesz wysłać rzeczy przez GET, nic nie stoi na przeszkodzie, aby wysłać żądanie do czegoś takiego, jak http://example.com/script.php?token=something&var1=val1&var2=val2umieszczenie tych wartości w GET.
Mike
14

Wersja jQuery:

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

Aktualizacja : jQuery 3:

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

Dzięki, Garrett

Paras
źródło
8

Dokumentacja tutaj zachęca do nasłuchiwania zdarzenia onbeforeunload i / lub dodawania detektora zdarzeń w oknie.

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

Możesz także po prostu wypełnić właściwości .onunload lub .onbeforeunload okna funkcją lub odwołaniem do funkcji.

Chociaż zachowanie nie jest ustandaryzowane w różnych przeglądarkach, funkcja może zwrócić wartość, którą przeglądarka wyświetli podczas potwierdzania opuszczenia strony.

davejoem
źródło
7

Możesz użyć window.onbeforeunload.

window.onbeforeunload = confirmExit;
function confirmExit(){
    alert("confirm exit is being called");
    return false;
}
Gurpreet Singh
źródło
3

Zdarzenie jest wywoływane beforeunload, więc możesz przypisać funkcję do window.onbeforeunload.

Phssthpok
źródło
-2

Możesz spróbować czegoś takiego:

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

<body onBeforeUnload="loadOut()">
Dane Balia
źródło
23
Uwaga, ludzie czytający to nie w starożytności - to jest starożytny JS i HTML, a inne sugestie tutaj są o wiele lepsze.
RAnders00