Pagina: DOMContentLoaded, load, beforeunload, unload

De levenscyclus van een HTML-pagina heeft drie belangrijke gebeurtenissen:

  • DOMContentLoaded – de browser heeft HTML volledig geladen en de DOM-structuur is gebouwd, maar externe bronnen zoals afbeeldingen <img> en stylesheets zijn mogelijk nog niet geladen.
  • load – niet alleen HTML wordt geladen, maar ook alle externe bronnen: afbeeldingen, stijlen etc.
  • beforeunload/unload – de gebruiker verlaat de pagina.

Elke gebeurtenis kan nuttig zijn:

  • DOMContentLoaded gebeurtenis – DOM is klaar , zodat de handler DOM-knooppunten kan opzoeken, de interface kan initialiseren.
  • load event – externe bronnen worden geladen, dus stijlen worden toegepast, afbeeldingsgrootten zijn bekend enz.
  • beforeunload evenement – de gebruiker vertrekt: we kunnen controleren of de gebruiker de wijzigingen heeft opgeslagen en vragen of ze echt willen vertrekken.
  • – de gebruiker is bijna vertrokken, maar we kunnen nog enkele bewerkingen starten, zoals het verzenden van statistieken.

Laten we de details van deze gebeurtenissen bekijken.

DOMContentLoaded

De DOMContentLoaded gebeurtenis vindt plaats op het document object.

We moet addEventListener gebruiken om het op te vangen:

Bijvoorbeeld:

In het voorbeeld wordt de DOMContentLoaded handler uitgevoerd wanneer het document is geladen, zodat het alle elementen kan zien, inclusief <img> hieronder.

Maar het wacht niet tot de afbeelding is geladen. Dus alert toont nulgroottes.

Op het eerste gezicht is de DOMContentLoaded -gebeurtenis heel eenvoudig. De DOM-structuur is klaar – hier is het evenement. Er zijn echter enkele eigenaardigheden.

DOMContentLoaded en scripts

Wanneer de browser een HTML-document verwerkt en een <script> tag tegenkomt, moet worden uitgevoerd voordat u doorgaat met het bouwen van de DOM. Dat is een voorzorgsmaatregel, aangezien scripts DOM willen wijzigen, en zelfs document.write erin, dus DOMContentLoaded moet wachten.

Dus DOMContentLoaded gebeurt zeker na dergelijke scripts:

In het bovenstaande voorbeeld zien we eerst “Bibliotheek geladen …”, en dan “DOM klaar!” (alle scripts worden uitgevoerd).

Scripts die DOMContentLoaded niet blokkeren

Er zijn twee uitzonderingen op deze regel:

  1. Scripts met het async attribuut, dat we later zullen behandelen, mogen DOMContentLoaded niet blokkeren.
  2. Scripts die dynamisch worden gegenereerd met document.createElement("script") en vervolgens aan de webpagina worden toegevoegd, blokkeren deze gebeurtenis ook niet.

DOMContentLoaded en stijlen

Externe style sheets hebben geen invloed op DOM, dus DOMContentLoaded wacht er niet op.

Maar er is een valkuil. Als we een script achter de stijl hebben, dan moet dat script wachten totdat het stijlblad is geladen:

De reden hiervoor is dat het script mogelijk coördinaten en andere stijlafhankelijke eigenschappen van elementen wil ophalen, zoals in het bovenstaande voorbeeld. Uiteraard moet het wachten tot stijlen zijn geladen.

Terwijl DOMContentLoaded op scripts wacht, wacht het nu ook op eerdere stijlen.

Ingebouwde browser automatisch aanvullen

Firefox, Chrome en Opera automatisch aanvullen formulieren op DOMContentLoaded.

Als de pagina bijvoorbeeld een formulier met login en wachtwoord, en de browser onthoudt de waarden, en op DOMContentLoaded kan het proberen om ze automatisch in te vullen (indien goedgekeurd door de gebruiker).

Dus als DOMContentLoaded wordt uitgesteld door lang ladende scripts, waarna automatisch aanvullen ook wacht. U hebt dat waarschijnlijk op sommige sites gezien (als u automatisch aanvullen via de browser gebruikt) – de login- / wachtwoordvelden worden niet onmiddellijk automatisch ingevuld, maar het duurt even voordat de pagina volledig is geladen. Dat is eigenlijk de vertraging tot de DOMContentLoaded -gebeurtenis.

window.onload

De load gebeurtenis op het window -object wordt geactiveerd wanneer de hele pagina wordt geladen, inclusief stijlen, afbeeldingen en andere bronnen. Deze gebeurtenis is beschikbaar via de eigenschap onload.

In het onderstaande voorbeeld worden de afbeeldingsformaten correct weergegeven, omdat window.onload wacht op alle afbeeldingen:

window.onunload

Wanneer een bezoeker de pagina verlaat, wordt de unload -gebeurtenis geactiveerd op window. We kunnen daar iets doen zonder vertraging, zoals het sluiten van gerelateerde pop-upvensters.

De opmerkelijke uitzondering is het verzenden van analyses.

Laten we zeggen dat we gegevens verzamelen over hoe de pagina is gebruikt: muisklikken, scrollen, bekeken paginagebieden, enzovoort.

Natuurlijk is de unload gebeurtenis wanneer de gebruiker ons verlaat, en we willen sla de gegevens op onze server op.

Het verzendt de gegevens op de achtergrond.De overgang naar een andere pagina wordt niet vertraagd: de browser verlaat de pagina, maar voert nog steeds sendBeacon uit.

Hier is hoe het te gebruiken:

  • Het verzoek wordt als POST verzonden.
  • We kunnen niet alleen een string verzenden, maar ook formulieren en andere formaten, zoals beschreven in het hoofdstuk Fetch, maar meestal is het een stringified object.
  • De gegevens zijn beperkt tot 64 kB.

Wanneer het sendBeacon -verzoek is voltooid, heeft de browser het document waarschijnlijk al verlaten, dus er is geen manier om een serverreactie te krijgen (die meestal leeg is voor analyse).

Er is ook een keepalive -markering voor het doen van dergelijke “after-page-left” -verzoeken in fetch-methode voor algemene netwerkverzoeken. U kunt meer informatie vinden in het hoofdstuk Fetch API.

Als we de overgang naar een andere pagina willen annuleren, kunnen we dit hier niet doen. Maar we kunnen een andere event – onbeforeunload.

window.onbeforeunload

Als een bezoeker de navigatie startte w ay van de pagina of probeert het venster te sluiten, de beforeunload handler vraagt om aanvullende bevestiging.

Als we de gebeurtenis annuleren, kan de browser de bezoeker vragen of ze zijn het zeker.

Je kunt het proberen door deze code uit te voeren en de pagina vervolgens opnieuw te laden:

Om historische redenen geldt het retourneren van een niet-lege string ook als annuleren de gebeurtenis. Enige tijd geleden lieten browsers het zien als een bericht, maar zoals de moderne specificatie zegt, zouden ze dat niet moeten doen.

Hier is een voorbeeld:

Het gedrag is gewijzigd , omdat sommige webmasters deze gebeurtenishandler hebben misbruikt door misleidende en irritante berichten weer te geven. Dus op dit moment kunnen oude browsers het nog steeds als een bericht weergeven, maar afgezien daarvan – er is geen manier om het bericht aan de gebruiker aan te passen.

readyState

Wat gebeurt er als we instellen de DOMContentLoaded handler nadat het document is geladen?

Natuurlijk wordt het nooit uitgevoerd.

Er zijn gevallen waarin we niet zeker weten of de document is klaar of niet. We willen dat onze functie wordt uitgevoerd wanneer de DOM wordt geladen, of het nu nu of later is.

De eigenschap document.readyState vertelt ons over de huidige laadstatus.

Er zijn 3 mogelijke waarden:

  • "loading" – het document wordt geladen.
  • "interactive" – het document is volledig gelezen.
  • "complete" – het document is volledig gelezen en alle bronnen (zoals afbeeldingen) zijn geladen ook.

We kunnen dus document.readyState controleren en een handler instellen of de code onmiddellijk uitvoeren als deze klaar is.

ook de readystatechange -gebeurtenis die wordt geactiveerd wanneer de toestand verandert, zodat we al deze toestanden als volgt kunnen afdrukken:

De readystatechange event is een alternatieve manier om de laadstatus van het document bij te houden, het verscheen lang geleden. Tegenwoordig wordt het zelden gebruikt.

Laten we de volledige gebeurtenissenstroom eens bekijken voor de volledigheid.

Hier is een document met <iframe>, <img> en handlers die gebeurtenissen loggen:

Het werkvoorbeeld bevindt zich in de sandbox.

De typische uitvoer:

De getallen tussen vierkante haakjes geven het geschatte tijdstip aan waarop het gebeurt. Gebeurtenissen met hetzelfde cijfer vinden ongeveer tegelijkertijd plaats (± een paar ms).

  • document.readyState wordt interactive vlak voor DOMContentLoaded. Deze twee dingen betekenen eigenlijk hetzelfde.
  • document.readyState wordt complete wanneer alle bronnen (iframe en img) worden geladen. Hier kunnen we zien dat het in ongeveer dezelfde tijd gebeurt als img.onload (img is de laatste bron) en window.onload. Overschakelen naar de status complete betekent hetzelfde als window.onload. Het verschil is dat window.onload altijd werkt na alle andere load handlers.

Samenvatting

Gebeurtenissen voor het laden van pagina’s:

  • De DOMContentLoaded -gebeurtenis wordt geactiveerd op document wanneer de DOM is klaar. We kunnen JavaScript in dit stadium op elementen toepassen.
    • Script zoals <script>https://javascript.info/...</script> of <script src="https://javascript.info/..."></script> blok DOMContentLoaded, de browser wacht zodat ze kunnen worden uitgevoerd.
    • Afbeeldingen en andere bronnen kunnen ook nog steeds worden geladen.
  • De load gebeurtenis op window wordt geactiveerd wanneer de pagina en alle bronnen worden geladen. We gebruiken het zelden, omdat je meestal niet zo lang hoeft te wachten.
  • De beforeunload -gebeurtenis op window wordt geactiveerd wanneer de gebruiker de pagina wil verlaten. Als we het evenement annuleren, vraagt de browser of de gebruiker echt wil vertrekken (we hebben bijvoorbeeld niet-opgeslagen wijzigingen).
  • Het unload evenement op window triggert wanneer de gebruiker eindelijk vertrekt, in de handler kunnen we alleen eenvoudige dingen doen die geen vertraging met zich meebrengen of een gebruiker vragen. Vanwege die beperking wordt het zelden gebruikt. We kunnen een netwerkverzoek verzenden met navigator.sendBeacon.
  • document.readyState is de huidige status van het document, wijzigingen kunnen worden gevolgd in de readystatechange -gebeurtenis:
    • loading – het document wordt geladen.
    • interactive – het document wordt geparseerd, gebeurt ongeveer op hetzelfde moment als DOMContentLoaded, maar ervoor.
    • complete – het document en de bronnen worden geladen, gebeuren ongeveer op hetzelfde moment als window.onload, maar daarvoor.

Leave a Reply

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *