Strona: DOMContentLoaded, load, beforeunload, unload

Cykl życia strony HTML ma trzy ważne zdarzenia:

  • DOMContentLoaded – przeglądarka w pełni załadowana HTML, a drzewo DOM jest zbudowane, ale zasoby zewnętrzne, takie jak obrazy <img> i arkusze stylów, mogły jeszcze nie zostać załadowane.
  • load – ładowany jest nie tylko HTML, ale także wszystkie zasoby zewnętrzne: obrazy, style itp.
  • beforeunload/unload – użytkownik opuszcza stronę.

Każde zdarzenie może być przydatne:

  • DOMContentLoaded zdarzenie – DOM jest gotowy , więc program obsługi może wyszukiwać węzły DOM, inicjować interfejs.
  • load zdarzenie – ładowane są zasoby zewnętrzne, więc stosowane są style, znane są rozmiary obrazów itp.
  • beforeunload zdarzenie – użytkownik wychodzi: możemy sprawdzić, czy użytkownik zapisał zmiany i zapytać, czy naprawdę chce wyjść.
  • – użytkownik prawie wyszedł, ale nadal możemy zainicjować pewne operacje, takie jak wysyłanie statystyk.

Przyjrzyjmy się szczegółom tych wydarzeń.

DOMContentLoaded

Zdarzenie DOMContentLoaded ma miejsce w obiekcie document.

Mamy musi użyć addEventListener, aby to złapać:

Na przykład:

W tym przykładzie moduł obsługi DOMContentLoaded działa po załadowaniu dokumentu, dzięki czemu może zobaczyć wszystkie elementy, w tym <img> poniżej.

Ale nie czeka na załadowanie obrazu. Dlatego alert pokazuje zero rozmiarów.

Na pierwszy rzut oka zdarzenie DOMContentLoaded jest bardzo proste. Drzewo DOM jest gotowe – oto wydarzenie. Jest jednak kilka osobliwości.

DOMContentLoaded i skrypty

Gdy przeglądarka przetwarza dokument HTML i napotyka tag <script>, musi zostać wykonana przed kontynuowaniem budowania DOM. To środek ostrożności, ponieważ skrypty mogą chcieć zmodyfikować DOM, a nawet wprowadzić do niego document.write, więc DOMContentLoaded musi poczekać.

Więc DOMContentLoaded na pewno dzieje się po takich skryptach:

W powyższym przykładzie najpierw widzimy „Biblioteka załadowana…”, a następnie „DOM gotowy!” (wykonywane są wszystkie skrypty).

Skrypty, które nie blokują DOMContentLoaded

Istnieją dwa wyjątki od tej reguły:

  1. Skrypty z atrybutem async, którym zajmiemy się nieco później, nie blokują DOMContentLoaded.
  2. Skrypty, które są generowane dynamicznie za pomocą document.createElement("script"), a następnie dodawane do strony internetowej, również nie blokują tego zdarzenia.

DOMContentLoaded i styles

Zewnętrzne arkusze stylów nie wpływają na DOM, więc DOMContentLoaded nie czeka na nie.

Ale jest pułapka. Jeśli po stylu mamy skrypt, musi on czekać, aż załaduje się arkusz stylów:

Powodem tego jest to, że skrypt może chcieć uzyskać współrzędne i inne zależne od stylu właściwości elementów, jak w powyższy przykład. Oczywiście musi czekać na załadowanie stylów.

Ponieważ DOMContentLoaded czeka na skrypty, teraz czeka również na style przed nimi.

Wbudowane autouzupełnianie przeglądarki

Firefox, Chrome i Opera autouzupełnianie formularzy w DOMContentLoaded.

Na przykład, jeśli strona ma formularz z loginem i hasłem, a przeglądarka zapamiętała wartości, to na DOMContentLoaded może spróbować je wypełnić automatycznie (jeśli zostanie to zaakceptowane przez użytkownika).

Więc jeśli DOMContentLoaded jest odkładane przez długo ładujące się skrypty, a następnie czeka na autouzupełnianie. Prawdopodobnie widziałeś to w niektórych witrynach (jeśli korzystasz z autouzupełniania przeglądarki) – pola logowania / hasła nie są automatycznie wypełniane od razu, ale pełne wczytanie strony jest opóźnione. W rzeczywistości jest to opóźnienie do zdarzenia DOMContentLoaded.

window.onload

load zdarzenie w obiekcie window jest wyzwalane po załadowaniu całej strony, w tym stylów, obrazów i innych zasobów. To zdarzenie jest dostępne za pośrednictwem właściwości onload.

Poniższy przykład poprawnie przedstawia rozmiary obrazów, ponieważ window.onload czeka na wszystkie obrazy:

window.onunload

Gdy użytkownik opuszcza stronę, zdarzenie unload uruchamia się na window. Możemy tam zrobić coś, co nie wiąże się z opóźnieniem, na przykład zamknąć powiązane okna wyskakujące.

Godnym uwagi wyjątkiem jest wysyłanie danych analitycznych.

Powiedzmy, że zbieramy dane o tym, jak strona jest używane: kliknięcia myszą, przewijanie, przeglądane obszary strony itd.

Oczywiście unload zdarzenie ma miejsce, gdy użytkownik nas opuszcza, a my chcielibyśmy zapisz dane na naszym serwerze.

Wysyła dane w tle.Przejście na inną stronę nie jest opóźnione: przeglądarka opuszcza stronę, ale nadal wykonuje sendBeacon.

Oto jak z tego korzystać:

  • Żądanie jest wysyłane jako POST.
  • Możemy wysłać nie tylko ciąg znaków, ale także formularze i inne formaty, jak opisano w rozdziale Pobieranie, ale zwykle jest to obiekt z ciągami znaków.
  • Dane są ograniczone do 64 kB.

Po zakończeniu żądania sendBeacon przeglądarka prawdopodobnie opuściła już dokument, więc nie ma sposobu, aby uzyskać odpowiedź serwera (która zwykle jest pusta do celów analitycznych).

Istnieje również flaga keepalive do wykonywania takich żądań „po lewej stronie” w metodzie pobierania dla ogólnych żądań sieciowych. Więcej informacji znajdziesz w rozdziale Fetch API.

Jeśli chcemy anulować przejście na inną stronę, nie możemy tego zrobić tutaj. Ale możemy użyć innej zdarzenie – onbeforeunload.

window.onbeforeunload

Jeśli użytkownik zainicjował nawigację aw ay ze strony lub próbuje zamknąć okno, moduł obsługi beforeunload prosi o dodatkowe potwierdzenie.

Jeśli anulujemy zdarzenie, przeglądarka może zapytać użytkownika, czy są pewni.

Możesz spróbować, uruchamiając ten kod, a następnie ponownie ładując stronę:

Ze względów historycznych zwrócenie niepustego ciągu również liczy się jako anulowanie wydarzenie. Jakiś czas temu przeglądarki wyświetlały to jako wiadomość, ale zgodnie ze współczesną specyfikacją nie powinny.

Oto przykład:

Zachowanie zostało zmienione , ponieważ niektórzy webmasterzy nadużyli tego modułu obsługi zdarzeń, wyświetlając mylące i irytujące komunikaty. W tej chwili stare przeglądarki mogą nadal wyświetlać to jako wiadomość, ale poza tym – nie ma możliwości dostosowania komunikatu wyświetlanego użytkownikowi.

readyState

Co się stanie, jeśli ustawimy moduł obsługi DOMContentLoaded po załadowaniu dokumentu?

Oczywiście nigdy nie działa.

Są przypadki, kiedy nie jesteśmy pewni, czy dokument jest gotowy czy nie. Chcielibyśmy, aby nasza funkcja wykonywała się po załadowaniu DOM, czy to teraz, czy później.

Właściwość document.readyState informuje nas o aktualnym stanie ładowania.

Istnieją 3 możliwe wartości:

  • "loading" – dokument się ładuje.
  • "interactive" – dokument został w pełni przeczytany.
  • "complete" – dokument został w pełni odczytany i wszystkie zasoby (takie jak obrazy) są załadowane też.

Możemy więc sprawdzić document.readyState i skonfigurować program obsługi lub natychmiast wykonać kod, jeśli jest gotowy.

Jest także zdarzenie readystatechange, które jest wyzwalane po zmianie stanu, więc możemy wydrukować wszystkie te stany w następujący sposób:

readystatechange to alternatywna mechanika śledzenia stanu ładowania dokumentu, pojawiła się dawno temu. W dzisiejszych czasach jest rzadko używany.

Zobaczmy pełny przepływ zdarzeń dla kompletności.

Oto dokument z <iframe>, <img> i programy obsługujące, które rejestrują zdarzenia:

Działający przykład znajduje się w piaskownicy.

Typowe dane wyjściowe:

liczby w nawiasach kwadratowych oznaczają przybliżony czas, w którym to się dzieje. Zdarzenia oznaczone tą samą cyfrą mają miejsce mniej więcej w tym samym czasie (± kilka ms).

  • document.readyState staje się interactive tuż przed DOMContentLoaded. Te dwie rzeczy właściwie oznaczają to samo.
  • document.readyState staje się complete, gdy wszystkie zasoby (iframe i img) są ładowane. Tutaj widzimy, że dzieje się to mniej więcej w tym samym czasie co img.onload (img to ostatni zasób) i window.onload. Przejście do stanu complete oznacza to samo, co window.onload. Różnica polega na tym, że window.onload zawsze działa po wszystkich innych modułach obsługi load.

Podsumowanie

Zdarzenia wczytywania strony:

  • Zdarzenie DOMContentLoaded uruchamia się w document, gdy DOM jest gotowy. Na tym etapie możemy zastosować JavaScript do elementów.
    • Skrypt taki jak <script>https://javascript.info/...</script> lub <script src="https://javascript.info/..."></script> blokuje DOMContentLoaded, przeglądarka czeka aby je wykonać.
    • Obrazy i inne zasoby mogą nadal się ładować.
  • load zdarzenie w window jest wyzwalane po załadowaniu strony i wszystkich zasobów. Rzadko go używamy, ponieważ zwykle nie ma potrzeby czekać tak długo.
  • Zdarzenie beforeunload w window jest wyzwalane, gdy użytkownik chce opuścić stronę. Jeśli anulujemy zdarzenie, przeglądarka zapyta, czy użytkownik naprawdę chce wyjść (np. Mamy niezapisane zmiany).
  • Zdarzenie unload w dniu window uruchamia się, gdy użytkownik w końcu wychodzi, w module obsługi możemy robić tylko proste rzeczy, które nie wymagają opóźnień ani nie pytają użytkownika. Z powodu tego ograniczenia jest rzadko używany. Możemy wysłać żądanie sieciowe z navigator.sendBeacon.
  • document.readyState to aktualny stan dokumentu, zmiany mogą być śledzone w zdarzeniu readystatechange:
    • loading – trwa ładowanie dokumentu.
    • interactive – dokument jest analizowany, dzieje się mniej więcej w tym samym czasie co DOMContentLoaded, ale przed nim.
    • complete – dokument i zasoby są ładowane, dzieje się mniej więcej w tym samym czasie co window.onload, ale przed nim.

Leave a Reply

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *