DOMContentLoaded im Head-Element der Seite
window.onload feuert nicht, bevor alle Bilder geladen wurden. Die modernen Browser haben ein Event DOMContentLoaded, das bereits feuert, wenn das DOM geladen ist und vom Script durchquert werden kann. DOMContentLoaded wird ab IE9 von allen modernen Browsern unterstützt und ist das Äquivalent zur jQuery $(function).
Das DOM ist noch nicht geladen, wenn das Script im head geparst wird. Elemente, auf die ein Zugriff erfolgen soll, existieren also noch nicht.
document.addEventListener ("DOMContentLoaded", () => { const marker = document.querySelector(".marker"); marker.innerHTML = "DOM geladen"; marker.addEventListener ("click", () => { marker.innerHTML = "Button aktiviert"; }); });
Wann ist das Bild geladen?
Das Laden von CSS-Dateien, Bildern und iframes blockiert die Ausführung von Scripts. Haben wir also ein <script> nach einem <link rel="stylesheet" ...>, wird die Seite nicht fertig geparst und DOMContentLoaded wird nicht feuern bis das Stylesheet geladen wurde.
<script> let i = 0; let images = []; let time = 3000; images [0] = "neptun-2400-1600.jpg"; images [1] = "berlin-2400-1600.jpg"; images [2] = "florenz-2400-1600.jpg"; function changeImg () { document.querySelector("#slide").src = images[i]; if (i < images.length -1) i++; else i = 0; setTimeout ("changeImg()", time); } document.addEventListener("DOMContentLoaded", function () { document.querySelector(".result").innerHTML = "Alles geladen! Warten auf die Bilder."; }); window.onload = changeImg; </script>
In diesem Beispiel wird DOMContentLoaded ausgeführt, wenn das Dokument geladen ist, aber wartet nicht auf das Laden aller Komponenten der Seite. Alles geladen! Warten auf die Bilder. taucht also vor dem Laden der Bilder auf.
Allerdings erzwingt auch das Laden externer Scripte (mit src, aber ohne asnyc oder defer) eine Pause im Aufbau der Seite. DOMContentLoaded feuert also erst nach der Ausführung externer Scripte.
Wenn das Dokument geladen ist
DOMContentLoaded unterscheidet sich von window.onload in einer weiteren Hinsicht: Es muß mit addEventListener abgefangen werden.
function ready() { console.log ("DOM geladen"); // Bild ist noch nicht geladen // falls es nicht vorher im Cache war let myImg = document.getElementById("myImg"); // wird myImg 0 0 console.log("myImg " + myImg.width + " " + myImg.height;); } document.addEventListener("DOMContentLoaded", ready);
Eine einfache Lösung für Scripte, die nicht auf Bilder, CSS-Dateien, iframes und andere externe Ressourcen warten müssen: Sie werden am Ende des Markups vor der schließenden Klammer des body-Tags geladen und nicht bereits im head-Element. Zwar wird auf diese Weise das Skript erst starten, wenn das Markup vollständig geladen ist, aber das Skript muss nicht auf das Laden der Bilder warten. Der Aufruf von Scripts am Ende des HTML-Dokuments ist heute de facto-Standard.
Aber Achtung: Auch am Ende der HTML-Datei kann sich ein Script also nicht darauf verlassen, dass die Bilder geladen sind: Vielleicht holt ein weiteres Script das Bild erst später (z.B. beim Scrollen der Seite).
DOMContentLoaded und CSS
Externe CSS-Dateien betreffen das DOM nicht, also wartet DOMContentLoaded nicht, bis sie geladen sind. Liegt das Script allerdings nach dem link-Tag der CSS-Datei, muss es warten bis die Stile ausgeführt wurden.