Flo: getElement -> document.write

Hi,

ich sitze hier vor einem externen Widget, das synchron geladen, vor allem im IE reichlich Verzögerung mit sich bringt. Ein Vorschlag den ich gefunden habe, liegt darin, das Script über var script=createElement('script') kurz vor dem abschliessenden body-Tag zu erstellen und das ganze über getElementById('scriptWrapper').appendChild('script') einzubinden. Mit dem Erfolg das IE8 mit dem Rendern der Seite immer noch auf sich warten lässt (die Differenz mit bzw. ohne kann man mit der Armbanduhr messen, von daher liegen hier wahrscheinlich auch noch andere Probleme) und dass die document.write Anweisungen irgendwie nicht im <div id="scriptWrapper" /> ausgeführt werden, sondern eben da, wo das Script-Element erstellt wird, was mich vor allem deswegen irritiert, da es ohne getElementById('scriptWrapper').appendChild('script') überhaupt nicht ausgeführt wird. Hat das alles so seine Richtigkeit oder gibt es irgendwelche Finten, Tricks oder auch Fallstricke die ich übersehen habe?

Danke schon mal...
Flo

  1. ich sitze hier vor einem externen Widget, das synchron geladen, vor allem im IE reichlich Verzögerung mit sich bringt. Ein Vorschlag den ich gefunden habe, liegt darin, das Script über var script=createElement('script') kurz vor dem abschliessenden body-Tag zu erstellen und das ganze über getElementById('scriptWrapper').appendChild('script') einzubinden.

    Das ist schon ein guter Tipp. Aber ein Script muss entsprechend umgeschrieben werden.

    Mit dem Erfolg das IE8 mit dem Rendern der Seite immer noch auf sich warten lässt (die Differenz mit bzw. ohne kann man mit der Armbanduhr messen, von daher liegen hier wahrscheinlich auch noch andere Probleme)

    Wahrscheinlich. Zeig am besten mal ein Beispiel.

    und dass die document.write Anweisungen irgendwie nicht im <div id="scriptWrapper" /> ausgeführt werden, sondern eben da, wo das Script-Element erstellt wird

    Das ist logisch. Es wundert mich, dass document.write überhaupt etwas dem Dokument hinzufügt. Wenn es asynchron und damit unabhängig vom Parsen des HTML-Codes aufgerufen wird, dann entfernt es den gesamten Dokumentinhalt und ersetzt ihn.

    document.write ist daher bei asynchronen Scripten unbrauchbar (vgl. JavaScript muss asynchron werden). Du müsstest stattdessen mit DOM-Methoden arbeiten, um den Code ins Dokument einzufügen (getElementById, innerHTML o.ä.).

    was mich vor allem deswegen irritiert, da es ohne getElementById('scriptWrapper').appendChild('script') überhaupt nicht ausgeführt wird.

    Das ist schon richtig. Ein script-Element bloß zu erstellen reicht nicht. Es muss zumindest temporär eingehängt werden.

    Mathias

    1. Das ist schon ein guter Tipp. Aber ein Script muss entsprechend umgeschrieben werden.

      Schlecht, weil es ein externes ist.

      Mit dem Erfolg das IE8 mit dem Rendern der Seite immer noch auf sich warten lässt (die Differenz mit bzw. ohne kann man mit der Armbanduhr messen, von daher liegen hier wahrscheinlich auch noch andere Probleme)

      Wahrscheinlich. Zeig am besten mal ein Beispiel.

      und dass die document.write Anweisungen irgendwie nicht im <div id="scriptWrapper" /> ausgeführt werden, sondern eben da, wo das Script-Element erstellt wird

      Das ist logisch. Es wundert mich, dass document.write überhaupt etwas dem Dokument hinzufügt. Wenn es asynchron und damit unabhängig vom Parsen des HTML-Codes aufgerufen wird, dann entfernt es den gesamten Dokumentinhalt und ersetzt ihn.

      Es wird ja synchron eingehängt.

      document.write ist daher bei asynchronen Scripten unbrauchbar (vgl. JavaScript muss asynchron werden). Du müsstest stattdessen mit DOM-Methoden arbeiten, um den Code ins Dokument einzufügen (getElementById, innerHTML o.ä.).

      was mich vor allem deswegen irritiert, da es ohne getElementById('scriptWrapper').appendChild('script') überhaupt nicht ausgeführt wird.

      Das ist schon richtig. Ein script-Element bloß zu erstellen reicht nicht. Es muss zumindest temporär eingehängt werden.

      Mach ich ja. Glaub ich jedenfalls. Hier das kurz zurechtgestutze Beispiel

      <html>
      <body>

      <div id="sourceWrapper">
        <!-- hier sollte die Ausgabe erfolgen... -->
        </div>
        <p>Davor/Danach-Element</p>

      <!-- ...aber sie erscheint hier -->

      <script type="text/javascript">
          (function () {
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.async = 'true';
            script.innerHTML = 'document.write("Ausgabe")';
            (document.getElementById('sourceWrapper')).appendChild(script);
          })();
        </script>

      <!-- und vielleicht kann mir jemand nebenher noch diese
             sonderbare Klammersyntax eläutern -->

      </body>
      </html>

      was ich in abgeänderter Form aus genau dem zitierten Artikel habe. Nur dass dort das Script in den Header verfrachtet wird und die Ausgabe dann in meinem Fall gleich nach dem öffnenden body-Tag erscheint.

      1. Das ist schon ein guter Tipp. Aber ein Script muss entsprechend umgeschrieben werden.
        Schlecht, weil es ein externes ist.

        Wenn das Script von dir nicht änderbar ist und synchron mit document.write arbeitet, dann kannst du das Script nicht asynchron einbinden, sondern musst es direkt mit <script src=""> einbinden. Das Script muss schon darauf vorbereitet sein.

        Wenn es asynchron und damit unabhängig vom Parsen des HTML-Codes aufgerufen wird, dann entfernt es den gesamten Dokumentinhalt und ersetzt ihn.
        Es wird ja synchron eingehängt.

        Ja, aber asynchron ausgeführt. Wenn es ausgeführt wird, ist das Dokument höchstwahrscheinlich schon geparst, daher ist es willkürlich, wo document.write Inhalte dem Dokument hinzufügt.

        <!-- und vielleicht kann mir jemand nebenher noch diese
               sonderbare Klammersyntax eläutern -->

        Das ist eine anonyme Funktion, die sofort ausgeführt wird. Sinn davon ist, dass man eine lokale Variable anlegen kann, die nicht den globalen Scope (das globale window-Objekt) „verunreinigt“. Siehe http://molily.de/js/organisation-module.html#scope.

        was ich in abgeänderter Form aus genau dem zitierten Artikel habe. Nur dass dort das Script in den Header verfrachtet wird und die Ausgabe dann in meinem Fall gleich nach dem öffnenden body-Tag erscheint.

        Wie gesagt, wenn du den HTML-Code an einer bestimmten Stelle einfügen willst, dann kann das Script kein document.write verwenden. Im Beispiel müsstest du den sourceWrapper ansprechen und z.B. mit getElementById und innerHTML:

        document.getElementById('sourceWrapper').innerHTML = 'Ausgabe';

        Grüße, Mathias

        1. Ok, langsam hab ichs. Bin halt leider nicht vom Fach. Danke vielmals...

          Ciao
          Flo