Alex: Skript nicht erst ausführen, wenn Seite vollständig geladen ist

Hallo,

ich höre in letzter Zeit immer öfter von "Unobtrusive Javascript". Eine Forderung dessen ist, dass JavaScript vollständig getrennt von HTML und in einer externen Datei ausgelagert sein soll - so wie man es idealerweise auch mit CSS macht.

So was ...

<a href="http://example.com/" onclick="popup('http://example.com/'); return false">Example</a>

... soll vermieden werden. Stattdessen soll das extern z.B. so gemacht werden:

document.getElementById('mylink').onclick = function()  
   {  
    popup(this.href);  
    return false;  
   }  

Mein Problem ist nun: ich kriege das JavaScript erst auf das HTML-Dokument angewendet, wenn die Seite vollständig geladen ist (z.B. mit window.onload).

Hier ist mal ein Beispiel zur Veranschaulichung: js-test-1.html
Erst wenn das Bild geladen ist, wird der Link im Popup geöffnet.

Möglich scheint es aber zu sein, dass das JavaScript auch schon vor dem vollständigen Laden ausgeführt wird. Mit jQuery geht es nämlich: js-test-2.html (zum Nachvollziehen Cache leeren)

Die Frage ist nur: wie (machen die das)?

Alex

  1. @@Alex:

    Mein Problem ist nun: ich kriege das JavaScript erst auf das HTML-Dokument angewendet, wenn die Seite vollständig geladen ist (z.B. mit window.onload).

    Im einfachsten Fall, indem du diesem Eventhandler ebenfalls eine anonyme Funktion zuweist, die das Gewünschte erledigt:

    window.onload = function ()  
    {  
      document.getElementById('mylink').onclick = function ()  
      {  
        popup(this.href);  
        return false;  
      };  
    };
    

    Zeigt 'this' auf das gewünschte Objekt?

    Live long and prosper,
    Gunnar

    --
    Erwebsregel 208: Manchmal ist das einzige, was gefährlicher als eine Frage ist, eine Antwort.
    1. Hallo Gunnar,

      window.onload = function ()

      {
        document.getElementById('mylink').onclick = function ()
        {
          popup(this.href);
          return false;
        };
      };

        
      Das ist doch im Prinzip genau das gleiche wie in [js-test-1.html](http://mylittlehomepage.net/files/tmp/js-test-1.html) gemacht wird. Erst wenn alles geladen ist, wird das Onclick-Event hinzugefügt. Oder habe ich was übersehen?  
        
      Alex
      
  2. Hallo,

    Möglich scheint es aber zu sein, dass das JavaScript auch schon vor dem vollständigen Laden ausgeführt wird. Mit jQuery geht es nämlich: js-test-2.html (zum Nachvollziehen Cache leeren)

    Die Frage ist nur: wie (machen die das)?

    Der load-Event feuert, wenn das Dokument mitsamt aller Ressourcen, d.h. Bilder, iframes usw. geladen ist.

    Beim Unobtrusive JavaScript ist es aber unwichtig, ob Bilder schon geladen sind. Man will schließlich nur auf den fertigen DOM-Elementenbaum zugreifen, um gewisse Element zu suchen bzw. anzusprechen und denen Event-Handler zu verpassen.

    Schau dir mal im (ungepackten) jQuery-Code die Funktion bindReady an. jQuery nutzt eine andere Möglichkeit als load. In erster Linie wird mit dem Event DOMContentLoaded gearbeitet. Der wird im Grunde genutzt wie load, feuert aber, sobald das DOM zur Verfügung steht. Den Event unterstützen fast alle modernen Browser.

    Für den IE und ältere Safaris gibt es Alternativlösungen. Die beruhen im Grunde allesamt darauf, dass gewisse Objekte abgefragt werden bzw. Funktionen aufgerufen werden, von denen man weiß, dass sie erst beim fertig geladenen DOM-Baum zur Verfügung stehen. Diese Abfragen werden in winzigen Abständen solange wiederholt, bis das DOM zur Verfügung steht. Dann werden alle Funktionen ausgeführt, die man mit $(function () { ... }) bzw. $(document).ready(...) registriert hat.

    Dann gibts für einige Browser noch Zusätze, damit gewartet wird, bis auch alle externen Stylesheets fertig geladen sind, damit deren Formatierungen schon auf die Elemente angewendet sind, wenn man darauf zugreift.

    Mathias

    1. Hallo Mathias,

      Danke für Deine hilfreiche Antwort! Ich habe mich bisher gescheut, genauer nachzusehen, was jQuery eigentlich macht. Es scheint aber doch mal einen Blick zu lohnen! DOMContentLoaded hört sich schon mal sehr interessant an. Nur schade, dass man wieder Workarounds benötigt, um möglichst viele Browser abzudecken.

      Alex