window.onbeforeunload nie działa na iPadzie?

84

Czy ktoś wie, czy onbeforeunloadwydarzenie jest obsługiwane na iPadzie i / lub czy istnieje inny sposób jego wykorzystania?

Próbowałem prawie wszystkiego i wygląda na to, że onbeforeunloadzdarzenie nigdy nie jest uruchamiane na iPadzie (przeglądarce Safari).

W szczególności próbowałem tego:

  • window.onbeforeunload = function(event) { event.returnValue = 'test'; }
  • window.onbeforeunload = function(event) { return 'test'; }
  • (oba powyższe razem)
  • window.onbeforeunload = function(event) { alert('test')'; }
  • (wszystkie powyższe funkcje, ale wewnątrz <body onbeforeunload="...">

Wszystkie te działają na FF i Safari na PC, ale nie na iPadzie.

Po załadowaniu strony wykonałem również następujące czynności:

alert('onbeforeunload' in window);
alert(typeof window.onbeforeunload);
alert(window.onbeforeunload);

Odpowiednio wyniki są następujące:

  • true
  • object
  • null

Tak więc przeglądarka ma tę właściwość, ale z jakiegoś powodu nie jest uruchamiana.

Sposoby opuszczania strony to klikanie przycisków Wstecz i Dalej, wyszukiwanie w Google na górnym pasku, zmiana lokalizacji na pasku adresu i kliknięcie zakładki.

Czy ktoś ma pojęcie o tym, co się dzieje? Byłbym bardzo wdzięczny za wszelkie uwagi.

Dzięki

Art Zambrano
źródło
Dziękuję wam obojgu za wasz wkład. To musi być jeden z wymienionych przez Ciebie powodów. Niestety nie ma oficjalnej dokumentacji firmy Apple dotyczącej tego i innych ograniczeń. Miejmy nadzieję, że wymyślą bardziej kreatywny sposób włączenia tej funkcji, jednocześnie zapobiegając jej złośliwemu użyciu. Bardzo często słyszę, że ludzie przypadkowo odchodzą od strony i tracą wszystkie dane, które wprowadzili w formularzu.
Art Zambrano,
Czy próbowałeś użyć addEventListener()?
Hello71
2
Jestem prawie pewien, beforeunloadże nie działa w Safari na iOS. :-( Może nie to, czego szukasz, ale mam sugestię, jak rzetelnie przetestować działaniebeforeunload
Peter V. Mørch
1
3 marca 2016 r. The window.onbeforeunload = function(event) { event.returnValue = 'test'; }nie działa zarówno w przeglądarce Chrome, jak i Safari w systemie iOS 9.2.1. Bardzo mi się podoba, onbeforeunloadponieważ strona nie zmienia się, jeśli kliknę anuluj.
vanduc1102
Wygląda na to, że ten problem został rozwiązany w Safari i iOS 13
Finesse

Odpowiedzi:

20

Zauważyłem, że zdarzenie onunload () jest uruchamiane. To zachowanie jest nieco dziwne; cokolwiek masz w swojej funkcji zwrotnej dołączonej do zdarzenia, jest faktycznie uruchamiane po załadowaniu nowej strony w tle (nie możesz jeszcze powiedzieć, że jest załadowana, ale logowanie serwera pokaże, że tak jest).

Co dziwniejsze, jeśli masz wywołanie confirm () w swoim onunload (), a użytkownik kliknął link, aby przejść gdzie indziej, jesteś w biznesie. Jeśli jednak użytkownik zamknie kartę przeglądarki iPad Safari, zdarzenie onunload () zostanie uruchomione, ale Twoje potwierdzenie () będzie miało niejawne anulowanie jako odpowiedź.

Danny Armstrong
źródło
Hm, wydaje się, że to potwierdzające dziwactwo (druga strona jest trafiana przed komunikatem potwierdzającym) jest prawdą nie tylko dla mobilnego safari, ale także dla Firefoxa (i prawdopodobnie innych). Po prostu rozwaliłeś mój umysł.
Amalgovinus
4
unloadzdarzenie wycofane na korzyść pagehidepatrz developer.apple.com/library/ios/documentation/AppleApplications/…
sol0mka
1
@ sol0mka: To wszystko, stary! Świetny! W moim przypadku następujący kod wykonał zadanie, o ile widzę dla wszystkich moich przeglądarek ORAZ iOS: $ (window) .on ('beforeunload pagehide', function () {// moje rzeczy, które muszą być zrobione na stronie zmiana } ); To powinna być akceptowana odpowiedź w moich oczach.
Garavani
18

Ten fragment JavaScript działa dla mnie w Safari i Chrome na iPadzie i iPhonie, a także na komputerach stacjonarnych / laptopach / innych przeglądarkach:

var isOnIOS = navigator.userAgent.match(/iPad/i)|| navigator.userAgent.match(/iPhone/i);
var eventName = isOnIOS ? "pagehide" : "beforeunload";

window.addEventListener(eventName, function (event) { 
    window.event.cancelBubble = true; // Don't know if this works on iOS but it might!
    ...
} );
Zagrożenie
źródło
1
Może złapać zdarzenie, ale jak możesz wyświetlić monit o potwierdzenie? Używanie return 'test';podobnego do tego przez op nie działa ..
user2335065
Dzięki, przegapiłem to w pierwotnym pytaniu. Nie testowałem tego specjalnie na iOS, ale prawdopodobnie dodanie tej dodatkowej linii zadziałałoby: window.event.cancelBubble = true; Dodam do mojej odpowiedzi
Niebezpieczeństwo
2
Dzięki, ale niestety to nie działa ... Próbowałem umieścić alert () wewnątrz niego, wygląda na to, że nowa strona zaczęła się ładować przed uruchomieniem funkcji alert (). Zobacz także: stackoverflow.com/questions/3239834/ ...
user2335065
@ user2335065 znalazłeś jakieś rozwiązanie dla tego samego.
Neeraj Rathod
chłopaki, czy znaleźliście jakieś rozwiązanie, aby wyświetlić monit o potwierdzenie przed opuszczeniem strony? Działa to dobrze w każdej przeglądarce z wyjątkiem IOS safari. Próbowałem też zdarzenia pagehide, ale nie zadziałało. Z góry dziękuję.
Rahul
6

Tylko Apple wiedziałoby na pewno, ale przypuszczam, że celowo nie włączyli tej funkcji w mobilnym Safari, ponieważ jest ona najczęściej używana przez podejrzane postacie, aby zmusić Cię do pozostania na ich stronie lub wyskakiwania wielu okien pornograficznych / reklamowych.

Charles Boyung
źródło
55
Lub wiesz, zapisz zmiany automatycznie, aby nie zostały utracone tylko z powodu przypadkowego dotknięcia niewłaściwej rzeczy.
Joel Mueller
4
Nie powiedziałem, że nie ma ważnych zastosowań, powiedziałem tylko, że to były najczęściej używane.
Charles Boyung,
3
@JoelMueller Twój komentarz powinien być zaakceptowaną odpowiedzią :)
sanchez
1
@JoelMueller To jest dokładnie mój przypadek użycia. Grrr @ apple
user2808054
@JoelMueller, czy możesz udostępnić dowolny oficjalny dokument, w którym możemy odnieść się do tego oświadczenia, że ​​mobilne safari automatycznie zapisuje zmiany.
Neeraj Rathod
3

W WebKit występuje znany błąd dotyczący włączenia przed pobraniem. Wydaje mi się, że zostało to naprawione w najnowszej wersji beta Chrome 5, ale całkiem możliwe, że przeglądarka iPada została utworzona z wersji WebKit, która nie ma poprawki.

Powiązany raport o błędzie Chrome .

Joel Mueller
źródło
1
Jestem zdezorientowany lub czy ten błąd nadal istnieje w przeglądarce iPada?
Peter
3

Zdarzenie beforeunload nie jest obsługiwane przez Mobile Safari. Możesz zobaczyć listę wszystkich obsługiwanych zdarzeń tutaj: Obsługa zdarzeń Dokumentacja Apple

A przedpunktu nie ma na liście!

Julien Bachmann
źródło
2

https://code.google.com/p/chromium/issues/detail?id=97035

zobacz, usłysz.

alerty nie są już dozwolone podczas zdarzeń związanych z odrzuceniem strony (przed załadowaniem, wyładowaniem, ukryciem strony).

Myślę, że alerty, monity, potwierdzenia i inne tego typu działania również nie są już dozwolone.

zelda.j
źródło
1

Jeśli chcesz tylko wiedzieć, czy strona została opuszczona, możesz użyć document.unload. Działa dobrze w przeglądarkach na iOS. Jeśli zobaczysz w dokumentacji Apple , zauważysz, że jest przestarzała i zalecają użycie document.pagehide

Miquel
źródło
tak, to zdarzenie uruchamia się w Safari, ale monit o potwierdzenie nie pojawia się tak, jak w Chrome.
Rahul
1

Oto rozwiązanie, które powinno działać we wszystkich nowoczesnych przeglądarkach:

var unloaded = false;
window.addEventListener("beforeunload", function(e)
{
    if (unloaded)
        return;
    unloaded = true;
    console.log("beforeUnload");
});
window.addEventListener("visibilitychange", function(e)
{
    if (document.visibilityState == 'hidden')
    {
        if (unloaded)
            return;
        unloaded = true;
        console.log("beforeUnload");
    }
});

Przeglądarki mobilne zwykle nie obsługują, beforeunloadponieważ przeglądarka może przejść do tła bez wyładowywania strony, a następnie w dowolnym momencie zostać zabita przez system operacyjny.

Większość przeglądarek komputerowych zawiera błąd, który powoduje, że visibilityStatenie są wywoływane po wyładowaniu dokumentu. Zobacz: tutaj .

Dlatego ważne jest, aby uwzględnić oba zdarzenia, aby uwzględnić wszystkie scenariusze.

NB

Użyłem console.logzamiast alertw moim przykładzie, ponieważ alertniektóre przeglądarki będą blokowane podczas wywoływania z beforeunloadlub visibilitychange.

Dan Bray
źródło