JavaScript-Event onLoad und die bessere Alternative

Die meisten Webentwickler kennen das JavaScript-Event onload. Dieses wird aufgerufen, sobald die komplette Seite geladen ist. Sie dient dann beispielsweise dazu, direkt nach dem Laden der Seite Änderungen durchzuführen. Nun gibt es allerdings ein großes Problem mit diesem Event – und dieses soll dieser Beitrag lösen.

Eigentlich ist das onload-Event eine feine Sache. Man kann sich sicher sein, dass der gesamte HTML-Code geladen ist und somit Änderungen ausführen. Würde es dieses Event nicht geben, müsste man die JavaScript-Funtion direkt aufrufen – und das ginge dann natürlich erst ganz am Ende des body-Tags bzw. nach dem zu bearbeitenden HTML-Element. Das hätte sehr hässlichen Code zur Folge. Viel schöner ist es doch den JS-Block in den Head der HTML-Datei zu schreiben oder sogar ganz auszulagern und dann darauf zu referenzieren.

Und doch ist das Event onload problematisch. Es wartet nämlich bis der gesamte Inhalt der Seite geladen wurde – das bedeutet: auch ALLE externen Ressourcen müssen erst vollständig geladen werden. Dazu gehören Bilder, Videos und sonstige externe Dateien. Zu diesem Zeitpunkt interagiert der User aber vielleicht schon mit der Seite, weil es ihm egal ist, ob da noch ein Bild oder Video lädt. Und das wiederum kann einerseits zu JavaScript-Fehlern führen, da der Entwickler per onload oft irgendwelche Funktionalitäten initialisiert und dann davon ausgeht, dass die Funktion sofort nach dem Aufruf für die User-Interaktion zur Verfügung steht. Es ist ja nicht unbedingt vertrauensbildend, wenn bei einem unbedarften User dann so ein tolles „Diese Seite enthält Fehler“ entgegenpoppt, wie der IE es bei JS-Fehlern anzeigt (bei entsprechender Einstellung, sonst zeigt er nur ein Ausrufezeichen unten links – aber auch das ist nicht schön).
Das zweite Problem ist, dass einfach eine Verzögerung eintritt. Der User möchte die Seite so schnell wie möglich benutzen – und es stört ihn garantiert, dass er eine bestimmte Funktion noch nicht nutzen kann, nur weil da noch ein Bild lädt (was mit der Funktion, die er nutzen möchte, vielleicht gar nichts zu tun hat).

Und wie lösen wir das Problemchen? Mit einem eigenen Eventchen.
Und zwar wollen wir ja eigentlich gar nicht warten bis das komplette Dokument mit allen externen Ressourcen geladen ist, sondern es würde vollkommen reichen, wenn alle DOM-Inhalte zur Verfügung stehen (das HTML-Dokument ist also vollständig geladen, sodass der DOM-Baum aufgebaut ist). Schon da können wir ja mit dem DOM arbeiten. Nativ bieten die Browser dafür leider keine Unterstützung, die für alle Browser gleichermaßen funktioniert, aber mit ein wenig Zusatzcode kann man den Seitenaufbau dadurch trotzdem beschleunigen.

//create onDomReady Event      
window.onDomReady = initReady;         
// Initialize event depending on browser       
function initReady(fn){
    //W3C-compliant browser
    if(document.addEventListener) {           
        document.addEventListener("DOMContentLoaded", fn, false);
    }       
    //IE       
    else { 
        document.onreadystatechange = function(){readyState(fn)} 
    }   
}//IE execute function       
function readyState(func) {       	
    // DOM is ready 
    if(document.readyState == "interactive" || document.readyState == "complete"){ 
                func();
    }
}

In Zeile 1 wird unser neues Event namens onDomReady initialisiert. Dies geschieht durch den Aufruf der Funktion initReady(). Diese prüft nun, ob der Browser das W3C-Event-Model unterstützt. Für den IE gibt es eine kleine Sonderbehandlung (wie üblich).

Aufgerufen wird das Event nun so:

    //execute as soon as DOM is loaded 
    window.onDomReady(onReady);  
    //do when DOM is ready 
    function onReady() {   
        alert("The DOM is ready!");
        }


//execute as soon as DOM is loaded window.onDomReady(onReady); //do when DOM is ready function onReady() { alert("The DOM is ready!"); }

Im Prinzip also genauso wie onload, nur eben jetzt mit dem neuen Event onDomReady.

Zur Anschauung gibt es eine kleine Demo , die das neue Event mit dem onload-Event vergleicht bzw. anzeigt, welches Event schneller da ist. Das funktioniert am besten mit leerem Cache, denn da werden die Unterschiede aufgrund des großen Bildes sichtbar.
Ich habe die Datei mit IE7 und FF3 unter Vista getestet. Ob die anderen Browser das auch verstehen, weiß ich nicht.
Große JS-Libraries wie jQuery oder Prototype haben ähnliche Funktionen, aber ich mag solche Monster nicht so gern, da die dem User erstmal 100 kB entgegenwerfen, obwohl man nur ganz wenige Funktionalitäten daraus nutzt.

Wem diese Mini-Funktion noch nicht reicht, der sollte auch mal den Beitrag bei The Future of the web ansehen. Dort ist eine etwas größere Funktion, die eventuell auch etwas mehr kann (hab ich nicht ausprobiert).


Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0