Moritz: Abhängigkeit von Javascript-Headern

Hallo liebe Forumsbesucher,

jetzt beschäftige ich mich schon sooo lange mit Javascript, bin aber nicht in der Lage, folgende Frage zu beantworten:

------------------------------
Angenommen meine HTML-Seite bindet im Header zuerst die Datei A.js und dann B.js ein. Kann ich jetzt in B.js ZUVERLÄSSIG Funktionen von A.js aufrufen?
------------------------------

Meines Wissens nach parst doch der Browser den HTML-Code und  sendet pro einzubindendem Header (also <script>-Tag) eine asynchrone(?) Anfrage nach der Datei an den Server. Im Falle dass A.js sehr groß und B.js sehr klein ist (und da per default min. 2 HTTP-Verbindungen gleichzeitig offen sein können), könnte doch B.js bereits vollständig geladen sein, A.js aber noch nicht. Dann werde ich doch sicherlich in B.js JS-Fehler bekommen, oder?

Genau das war z.B. der Fall als ich vor nem halben Jahr mal versucht hab mit AJAX JS-Header On-Demand nachzuladen (siehe http://ajaxpatterns.org/On-Demand_Javascript). Damals hab ich die Downloads praktisch manuell synchronisiert. Das heißt ich hab die Downloads in ne Warteschlange gesteckt und den nächsten erst gestartet, wenn der vorherige vollständig geladen war. Letzteres hab ich durch einen speziellen Methodenaufruf am Ende jedes nachzuladenden Header kenntlich gemacht.

Meine jetztige Frage bezieht sich aber erstmal nicht auf den AJAX-Fall, sondern auf eine stink-normale HTML-Seite mit mehreren Headern. Ich meine prinzipiell sind doch heute alle AJAX-Bibliotheken nach dem modularen Muster aufgebaut. Zum Beispiel YUI: die fordert, dass zuerst das modul "yahoo.js" eingebunden werden muss bevor ich beispielsweise mit dem modul "event.js" arbeiten kann. Laut Doku reicht es immer die Header in der richtigen Reihenfolge einzubinden. Intern habe ich da auch keine Prüfung auf fertig geladene Abhängigkeiten gefunden...

Wär super wenn ihr mir euer Wissen mitteilen könntet.

Danke,
Moritz

  1. Angenommen meine HTML-Seite bindet im Header zuerst die Datei A.js und dann B.js ein. Kann ich jetzt in B.js ZUVERLÄSSIG Funktionen von A.js aufrufen?

    Ja.

    Struppi.

    1. Ja.

      Danke Struppi. Kannst du mir auch noch sagen warum, bzw. mir die Links auf entsprechende Quellen schicken?

      Danke.

      Moritz

      1. Ja.

        Danke Struppi. Kannst du mir auch noch sagen warum, bzw. mir die Links auf entsprechende Quellen schicken?

        Nein. Das ist lediglich ein Erfahrungswert. Wenn du mit <script..> die Skripte einbindest sind die Funktionen immer für alle anderen Module verfügbar. Im gegensatz zu mit document.write('<script...>') eingebundenen

        Struppi.

        1. Nein. Das ist lediglich ein Erfahrungswert. Wenn du mit <script..> die Skripte einbindest sind die Funktionen immer für alle anderen Module verfügbar. Im gegensatz zu mit document.write('<script...>') eingebundenen

          Ja, aus Erfahrung kann ich das auch sagen, aber ich hätte es gern halt wo stehen gehabt. Na ja, danke jedenfalls, Struppi.

          Vielleicht weiß ja jemand anderes noch ne zuverlässige Quelle.

          Grüße,
          Moritz

          1. Vielleicht weiß ja jemand anderes noch ne zuverlässige Quelle.

            Es ist lediglich eine Frage, was wann wie ausgeführt wird. Ein HTML-Dokument wird "von oben nach unten" geparst und die entsprechenden Ressourcen eingelesen. Bindest du zwei JS-Dateien ein, die zueinander Bezug haben, kannst du während des Renderns nur auf die Funktionen direkt zugreifen, die zu diesem Zeitpunkt auch bereits geladen wurden. Beispiel:

            test1.js:
            ---------

            boo = (typeof foo == 'function') ? foo() : 42;  
              
            window.onload = function() { alert(boo) };
            

            test2.js:
            ---------

            function foo() {  
              return 'foo';  
            }
            

            Bindest du erst test1.js ein und dann test2.js, gibt dir dein alert '42' aus. Lädst du erst test2.js und dann test1.js, erhältst du das erwartete 'foo'. Dies ist wichtig für Initialisierungen, die du direkt (also nicht in eine Funktion verpackt) vornimmst. Wenn du aber die Variable boo nicht wie in meinem Beispiel während des Renderns initialisierst, sondern in einer eigenen Funktion, dann ist die Reihenfolge, in der test1.js und test2.js geladen werden, in der Tat wurscht, da Funktionen zwar geparst, aber nicht wie meine Variablenzuweisung noch während des Ladens ausgeführt werden:

            test1.js:
            ---------

            window.onload = function() {  
              boo = (typeof foo == 'function') ? foo() : 42;  
              alert(boo);  
            }
            

            Denn hier wird die Funktion onload aufgerufen, also erst dann, wenn das Dokument vollständig geladen wurde. Selbst wenn die alert-Funktion innerhalb des Body aufgerufen werden würde, gibt es im Normalfall keine Probleme, da vor dem Body alle Elemente im Head geladen werden. Einzig für "riesige" JS-Dateien fehlen mir Erfahrungswerte, ob es in diesen Fällen dahingehend zu Problemen kommen könnte, dass der HTML-Code schon gerendert ist, die JS-Datei(en) aber noch nicht vollständig geladen wurden.

            Siechfred

            --
            Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
            1. [...]

              Vielen Dank für deine verständlichen Ausführungen. Soweit ist und war mir die Sache klar. Interessant wirds hier:

              » gibt es im Normalfall keine Probleme, da vor dem Body alle Elemente im Head geladen werden.

              Geladen werden, aber nicht zwingend vollständig geladen sind, wie du weiterhin selbst anmerkst:

              » Einzig für "riesige" JS-Dateien fehlen mir Erfahrungswerte, ob es in diesen Fällen dahingehend zu Problemen kommen könnte, dass der HTML-Code schon gerendert ist, die JS-Datei(en) aber noch nicht vollständig geladen wurden.

              Kommt darauf an was man als riesig bezeichnet bzw. wie wenig an HTML zu rendern ist. Angenommen ich lade ne größere Ajax-Bibliothek, hab im BODY kein HTML sondern nur einen JS-Block, der die geladene Bib erfordert... Na ja, aber das scheint mir doch eher der Sonderfall zu sein.

              Grüße Moritz

          2. Vielleicht weiß ja jemand anderes noch ne zuverlässige Quelle.

            Im Zweifelsfall den Quellcode eines offenen Browsers.

            Der Punkt ist, es muss ja so sein, dass die Skripte nacheinander geparst werden, denn in jedem ausgelagerten Skript kann z.b. ein document.write() vorkommen und dies müßte dann unmittelbar ausgeführt und gerendert werden

            Struppi.

            1. Hi,

              Der Punkt ist, es muss ja so sein, dass die Skripte nacheinander geparst werden, denn in jedem ausgelagerten Skript kann z.b. ein document.write() vorkommen und dies müßte dann unmittelbar ausgeführt und gerendert werden

              Es sei denn, man schließt das als (man sollte als Autor ja wissen, was drin ist ;-)). Dann kann man dem Script-Element das Attribut DEFER mitgeben. Für den Browser bedeutet das dann, daß er nicht auf das Script warten muß ...

              Gruß, Cybaer

              --
              Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
              1. Der Punkt ist, es muss ja so sein, dass die Skripte nacheinander geparst werden, denn in jedem ausgelagerten Skript kann z.b. ein document.write() vorkommen und dies müßte dann unmittelbar ausgeführt und gerendert werden

                Es sei denn, man schließt das als (man sollte als Autor ja wissen, was drin ist ;-)). Dann kann man dem Script-Element das Attribut DEFER mitgeben. Für den Browser bedeutet das dann, daß er nicht auf das Script warten muß ...

                Joh, steht auch so beim w3c http://www.w3.org/TR/html4/interact/scripts.html#adef-defer

                Struppi.

                1. Joh, steht auch so beim w3c http://www.w3.org/TR/html4/interact/scripts.html#adef-defer

                  Ah ok, danke euch allen.