Livscykeln för en HTML-sida har tre viktiga händelser:
-
DOMContentLoaded
– webbläsarens fullastade HTML och DOM-trädet är byggt, men externa resurser som bilder<img>
och stilark kanske inte har laddats ännu. -
load
– inte bara HTML laddas, utan också alla externa resurser: bilder, stilar etc. -
beforeunload/unload
– användaren lämnar sidan.
Varje händelse kan vara användbart:
-
DOMContentLoaded
händelse – DOM är redo , så att hanteraren kan leta upp DOM-noder, initiera gränssnittet. -
load
händelse – externa resurser laddas, så format tillämpas, bildstorlekar är kända etc. -
beforeunload
händelse – användaren lämnar: vi kan kontrollera om användaren sparade ändringarna och fråga dem om de verkligen vill lämna. - – användaren lämnade nästan, men vi kan fortfarande initiera vissa operationer, till exempel att skicka ut statistik.
Låt oss utforska detaljerna i dessa händelser.
DOMContentLoaded
DOMContentLoaded
händelsen inträffar på document
-objektet.
Vi måste använda addEventListener
för att fånga det:
Till exempel:
I exemplet körs DOMContentLoaded
-hanteraren när dokumentet laddas, så att det kan se alla element, inklusive <img>
nedan.
Men det väntar inte på att bilden laddas. Så alert
visar nollstorlekar.
Vid första anblicken är händelsen DOMContentLoaded
väldigt enkel. DOM-trädet är klart – här är evenemanget. Det finns dock få särdrag.
DOMContentLoaded och skript
När webbläsaren bearbetar ett HTML-dokument och stöter på en <script>
-tagg, måste köra innan du fortsätter bygga DOM. Det är en försiktighetsåtgärd, eftersom skript kanske vill ändra DOM och till och med document.write
i den, så DOMContentLoaded
måste vänta.
Så DOMContentLoaded händer definitivt efter sådana skript:
I exemplet ovan ser vi först ”Biblioteket laddat …” och sedan ”DOM redo!” (alla skript körs).
Det finns två undantag från denna regel:
- Skript med
async
attribut, som vi kommer att täcka lite senare, blockera inteDOMContentLoaded
. - Skript som genereras dynamiskt med
document.createElement("script")
och sedan läggs till på webbsidan blockerar inte heller den här händelsen.
DOMContentLoaded and styles
Externa stilark påverkar inte DOM, så DOMContentLoaded
väntar inte på dem.
Men det finns en fallgrop. Om vi har ett skript efter stilen måste skriptet vänta tills stilarket laddas:
Anledningen till detta är att skriptet kanske vill få koordinater och andra stilberoende egenskaper hos element, som i exemplet ovan. Naturligtvis måste den vänta på att stilar ska laddas.
Eftersom DOMContentLoaded
väntar på skript, väntar det nu också på stilar före dem.
Inbyggd webbläsare autofyll
Firefox, Chrome och Opera autofyll formulär på DOMContentLoaded
.
Till exempel om sidan har en formulär med inloggning och lösenord, och webbläsaren kom ihåg värdena, sedan på DOMContentLoaded
kan det försöka fylla i dem automatiskt (om användaren godkänner det).
Så om DOMContentLoaded
skjuts upp med skript med lång laddning, sedan väntar också autofyll. Du såg antagligen att det på vissa webbplatser (om du använder webbläsarens autofyll) – inloggnings- / lösenordsfälten fylls inte automatiskt omedelbart, men det finns en fördröjning tills sidan laddas helt. Det är faktiskt förseningen tills DOMContentLoaded
-händelsen.
window.onload
load
händelsen på window
objektet utlöses när hela sidan laddas inklusive stilar, bilder och andra resurser. Den här händelsen är tillgänglig via egenskapen onload
.
Exemplet nedan visar korrekt bildstorlekar, eftersom window.onload
väntar på alla bilder:
window.onunload
När en besökare lämnar sidan utlöses unload
-händelsen på window
. Vi kan göra något där som inte innebär en fördröjning, som att stänga relaterade popup-fönster.
Det anmärkningsvärda undantaget är att skicka analyser.
Låt oss säga att vi samlar in data om hur sidan är används: musklick, rullar, visade sidområden och så vidare.
Naturligtvis är unload
händelsen när användaren lämnar oss, och vi skulle vilja spara data på vår server.
Den skickar data i bakgrunden.Övergången till en annan sida är inte försenad: webbläsaren lämnar sidan men utför fortfarande sendBeacon
.
Så här använder du den:
- Begäran skickas som POST.
- Vi kan inte bara skicka en sträng utan också formulär och andra format, som beskrivs i kapitlet Hämta, men vanligtvis är det ett strängat objekt.
- Uppgifterna är begränsade till 64 kb.
När sendBeacon
begäran är klar har webbläsaren troligen redan lämnat dokumentet, så det finns inget sätt att få serversvar (som vanligtvis är tomt för analys).
Det finns också en keepalive
-flagga för att göra sådana ”efter-sida-vänster” -förfrågningar i hämtningsmetod för generiska nätverksförfrågningar. Du kan hitta mer information i kapitlet Hämta API.
Om vi vill avbryta övergången till en annan sida kan vi inte göra det här. Men vi kan använda en annan händelse – onbeforeunload
.
fönster. före laddning
Om en besökare initierade navigering aw ay från sidan eller försöker stänga fönstret, beforeunload
hanteraren ber om ytterligare bekräftelse.
Om vi avbryter händelsen kan webbläsaren fråga besökaren om de är säkra.
Du kan prova det genom att köra koden och sedan ladda om sidan:
Av historiska skäl räknas också att en icke-tom sträng returneras händelsen. För en tid sedan visade webbläsare det som ett meddelande, men som den moderna specifikationen säger, borde de inte.
Här är ett exempel:
Uppförandet ändrades , eftersom vissa webbansvariga missbrukade denna händelsehanterare genom att visa vilseledande och irriterande meddelanden. Så just nu kan gamla webbläsare fortfarande visa det som ett meddelande, men förutom det – det finns inget sätt att anpassa meddelandet som visas för användaren.
readyState
Vad händer om vi ställer in DOMContentLoaded
-hanteraren efter att dokumentet har laddats?
Naturligtvis körs det aldrig.
Det finns fall där vi inte är säkra på om dokumentet är klart eller inte. Vi vill att vår funktion ska köras när DOM laddas, vare sig det är nu eller senare.
Egenskapen document.readyState
berättar om det aktuella laddningstillståndet.
Det finns tre möjliga värden:
-
"loading"
– dokumentet laddas. -
"interactive"
– dokumentet lästes fullständigt. -
"complete"
– dokumentet lästes fullständigt och alla resurser (som bilder) laddas också.
Så vi kan kontrollera document.readyState
och ställa in en hanterare eller utföra koden omedelbart om den är redo.
Det finns även readystatechange
händelsen som utlöses när tillståndet ändras, så att vi kan skriva ut alla dessa tillstånd så här:
readystatechange
händelse är en alternativ mekanik för att spåra dokumentets laddningstillstånd, det verkade för länge sedan. Numera används det sällan.
Låt oss se hela händelseflöden för fullständigheten.
Här är ett dokument med <iframe>
, <img>
och hanterare som loggar händelser:
Arbetsexemplet finns i sandlådan.
Den typiska utgången:
siffror inom hakparenteser anger ungefärlig tid när det händer. Händelser märkta med samma siffra inträffar ungefär samtidigt (± några ms).
-
document.readyState
blirinteractive
precis föreDOMContentLoaded
. Dessa två saker betyder faktiskt samma. -
document.readyState
blircomplete
när alla resurser (iframe
ochimg
) är laddade. Här kan vi se att det händer ungefär samtidigt somimg.onload
(img
är den sista resursen) ochwindow.onload
. Att byta tillcomplete
tillstånd betyder samma somwindow.onload
. Skillnaden är attwindow.onload
alltid fungerar efter alla andraload
hanterare.
Sammanfattning
Sidhämtningshändelser:
-
DOMContentLoaded
-händelsen utlöses pådocument
när DOM är redo. Vi kan tillämpa JavaScript på element i detta skede.- Skript som
<script>https://javascript.info/...</script>
eller<script src="https://javascript.info/..."></script>
blockerar DOMContentLoaded, webbläsaren väntar för att de ska kunna köras. - Bilder och andra resurser kan också fortsätta att laddas.
- Skript som
-
load
händelse påwindow
utlöses när sidan och alla resurser laddas. Vi använder det sällan eftersom det vanligtvis inte behövs vänta så länge. -
beforeunload
-händelsen påwindow
utlöses när användaren vill lämna sidan. Om vi avbryter händelsen frågar webbläsaren om användaren verkligen vill lämna (t.ex. att vi har ändringar som inte har sparats). -
unload
-händelsen påwindow
utlöses när användaren äntligen lämnar, i hanteraren kan vi bara göra enkla saker som inte innebär förseningar eller att fråga en användare. På grund av den begränsningen används den sällan. Vi kan skicka en nätverksförfrågan mednavigator.sendBeacon
. -
document.readyState
är dokumentets nuvarande tillstånd, ändringar kan spåras ireadystatechange
-händelsen:-
loading
– dokumentet laddas. -
interactive
– dokumentet analyseras, sker ungefär samtidigt somDOMContentLoaded
, men innan det. -
complete
– dokumentet och resurserna laddas, händer ungefär samtidigt somwindow.onload
, men innan det.
-