Jak zapobiegać alertom JavaScript, które uruchamiają się po opuszczeniu strony?

12

Wiele stron ma alerty, gdy je opuszczasz: jeśli zamykasz karty, nawigujesz bez zapisywania itp., Istnieje wiele powodów, dla których witryna ostrzega / blokuje odejście do czasu potwierdzenia, np. „Czy na pewno chcesz nawigować poza tą stroną? ”.

Zazwyczaj odbywa się to za pomocą onbeforeunloadi / lub onunloadprogramów obsługi.

Oto przykład.

Czy jest jakiś sposób, aby zapobiec alertom / zdarzeniom blokującym użytkownika generowanym przez te programy obsługi? Zasadniczo chciałbym pozostawić włączoną JS, a konkretnie zabronić rzeczy, które uniemożliwiłyby mi opuszczenie strony bez dodatkowego kliknięcia.

onbeforeunloadi przewodnicy onunloadpowinni nadal strzelać; po prostu nie powinny mieć możliwości robienia rzeczy, które blokują użytkownika. Oznacza to brak alertów i operacji trwających dłużej niż kilka sekund.

Znalazłem kilka wtyczek, które edytują / greasemonkey łatają javascript dla poszczególnych stron, i grałem trochę z ich kodem, aby spróbować je uniwersalnie zastosować. Mam jednak nadzieję znaleźć rozwiązanie, które działa na każdej stronie, która próbuje zablokować wyjście użytkownika.

Zac B
źródło
Czy możesz opublikować adres URL, który to robi?
golimar
Edytowano, dodano przykład. Rozumiem również, dlaczego takie zachowanie jest często pożądane i że jest potrzebne, aby zapobiec przypadkowej utracie danych w wielu przypadkach. Nadal chciałbym wiedzieć, jak to zmienić / wyłączyć.
Zac B
Uwaga: cała bieżąca odpowiedź (która modyfikuje onbeforeunload) będzie działać tylko dla stron, które używają onbeforeunload, a nie dla stron, które używają jednej z innych metod dołączania zdarzeń.
Synetech

Odpowiedzi:

7

Najprostszą rzeczą jest po prostu zastąpienie skryptu stron i ponowne przypisanie zdarzenia null.

window.onbeforeunload = null;

Powinno to działać w dowolnym miejscu, chyba że są naprawdę złośliwe, i sami nadal go przypisują. W takim przypadku pętla do ustawienia nullbędzie prawdopodobnie działać.

while(true) {
    if (window.onbeforeunload != null) {
        window.onbeforeunload = null;
    }
}

Ostrzegamy, że niektóre strony używają tego na dobre. Przejdź na stronę przesyłania do YouTube: jeśli opuścisz stronę podczas przesyłania, być może straciłeś godziny postępu! A może formularz internetowy, który wypełniasz, którego możesz nie chcieć wypełniać ponownie, lub wiadomość (forum / e-mail), której możesz nie chcieć pisać ponownie. Dzięki tej funkcji jesteś chroniony.

Innym problemem jest każda strona korzystająca z niej do jakiegoś dodatkowego celu, takiego jak zapisywanie danych przez AJAX. Mogą użyć tego zdarzenia, aby uruchomić akcję zapisywania, i mają nadzieję, że użytkownik kliknie przycisk wystarczająco długo, aby przejść do żądania. Ponownie często robi się to, aby cię uratować.

Ale oczywiście wszyscy wiemy, że wiele stron używa tego do chorych. Więc jeśli znasz jakieś strony, na których chcesz, aby działało, zawsze możesz mieć system białej listy. Naprawdę nie ma sposobu, aby zablokować tę akcję bez całkowitego zablokowania window.onbeforeunloadi wszelkich (być może dobrych) akcji, które mogłaby podjąć.

Nie ma sposobu (bez wcześniejszej znajomości kodu danego strony) na zachowanie dobrych działań przy zatrzymywaniu wyskakującego okienka. To pudełko nie jest alert(). Okno jest generowane przez przeglądarkę jako zamierzone zachowanie onbeforeunload. Można go window.onbeforeunloadutworzyć, wykonując dowolną przypisaną funkcję w celu zwrócenia ciągu. Ten ciąg zostanie wydrukowany w wyskakującym okienku.

window.onbeforeunload = function() {
    //Whatever
    return "WARNING! You have unsaved changes that may be lost!";
}

W związku z tym nie można zablokować wyskakującego okienka bez kasowania funkcji.

Ponadto, jeśli znajdziesz sposób, dowolny AJAX zawiedzie. Wyskakujące okienko daje czas na przesłanie żądań, bez niego dane mogą zostać utracone.

Jeśli chodzi o onunloadto, nie powinno być możliwe zablokowanie cię tym. Ponieważ jest uruchamiany po zwolnieniu strony. Ale dla bezpieczeństwa zawsze możesz to zrobić window.onunload = null;i należy o to zadbać.

zeel
źródło
Ten rodzaj działa, ale co, jeśli przewodnik onbeforeunloadzrobi coś jeszcze ważnego? Na przykład, co zrobić, jeśli zwróci się z krótkim żądaniem AJAX lub powierzy coś w lokalnej pamięci HTML5? Czy istnieje sposób, aby po prostu uniemożliwić onbeforeunloadprogramom obsługi wykonywanie określonych połączeń (tj. alert()) Lub działanie dłużej niż przez określony czas? Dlatego zapytałem o rozszerzenie, a nie tylko skrypt typu fatmonkey: wydaje się, że aby zrobić to dobrze, trzeba by coś zmienić na poziomie silnika JavaScript.
Zac B
1
Dodałem więcej informacji. Jeśli chodzi o naprawienie tego na niższym poziomie, rozszerzenia nie są w rzeczywistości na niższym poziomie. Mają wyższe uprawnienia i niektóre specjalne interfejsy API, ale nie mają możliwości zmiany podstawowych funkcji przeglądarki. Nie jestem pewien, jak głęboko może zejść wtyczka FF, nie mam doświadczenia w tej dziedzinie. Oczywiście, będąc open source, możesz dokonać tych zmian. Ale to trochę daleko, aby naprawić wyskakujące okienko.
zeel
Nie działa dla mnie :(
Phuc Nguyen
0
    // ==/UserScript==

var th = document.getElementsByTagName('body')[0];
var s = document.createElement('script');
s.setAttribute('type','text/javascript');
s.innerHTML = "window.onbeforeunload = function() {}";
th.appendChild(s);
ktokolwiek
źródło
1
Dlaczego miałbyś kiedykolwiek tworzyć taki skrypt?
Brad
3
@ktokolwiek. Pomocne może być wyjaśnienie skryptu, aby inni mogli wiedzieć, co robią. Pozwoliłoby to również na skorzystanie z odpowiedzi przez wielu, ponieważ określony fragment skryptu może zostać zmieniony w celu ulepszenia skryptu lub fragment może być użyty w zupełnie innym skrypcie. Dobrym pomysłem jest również wyjaśnienie odpowiedzi, aby pomóc ludziom dowiedzieć się, jak to dotyczy ich pytania. Dziękujemy za opublikowanie odpowiedzi.
David
0

Jest ładne narzędzie, które poradzi sobie z każdym irytującym oknem wyskakującym w systemie Windows - ClickOff . Możesz go pobrać stąd . Sprawdziłem to i działa z alertem „Wprowadzone zmiany mogą nie zostać zapisane” dla witryny SharePoint.

Serhiy
źródło