Ralf: JS dynamisch nachladen

Hallo!

Ich bin durch einen Hinweis hier im Forum auf ein Script gestoßen, welches das dynamische Nachladen von Javascript ermöglicht:
http://sniplets.anaboe.net/javascript06.html

Damit habe ich aber nun Probleme, weil ich den Code, der das Nachladen durchführen soll, erst zur Laufzeit in ein leeres Popup schreibe.

Grundsätzlich funktioniert das Laden dort auch (zwar nicht über onLoad, sondern direkt im Code), jedoch kann ich die geladenen Funktionen nicht sofort aufrufen, sondern sozusagen erst asynchron.

Wenn also in dem Popup *nach* dem Laden Funktionen z.B. per onClick() aufgerufen werden, klappt es.

Ich habe mir jetzt überlegt, in dem sofort ausgeführten Teil des Popups nur das Nachladen durchzuführen und die weitere Verarbeitung per setTimeout() zu verzögern.

Macht das Sinn oder gibt es eine andere Möglichkeit?

Und wie kann ich sicher stellen, dass das Nachladen auch tatsächlich funktioniert hat? Es wird ja in jedem Fall ein Script-Element erzeugt, auch wenn der Code nicht geladen werden konnte.

Ralf

  1. Hallo Ralf

    Grundsätzlich funktioniert das Laden dort auch (zwar nicht über onLoad, sondern direkt im Code), jedoch kann ich die geladenen Funktionen nicht sofort aufrufen, sondern sozusagen erst asynchron.

    Natürlich, erst wenn die Resource wirklich geladen ist.

    Wenn also in dem Popup *nach* dem Laden Funktionen z.B. per onClick() aufgerufen werden, klappt es.

    Wobei das dann wohl auch davon abhängt, ob das Laden oder der Klick
    schneller war.

    Ich habe mir jetzt überlegt, in dem sofort ausgeführten Teil des Popups nur das Nachladen durchzuführen und die weitere Verarbeitung per setTimeout() zu verzögern.

    Notlösung!
    Du weißt nicht, wie lang die Verzögerung sein muss, da du kaum Einfluss
    darauf hast, wie lange das Nachladen benötigt. (z.b. könnte der Server
    kurzzeitig überlastet sein)

    Macht das Sinn oder gibt es eine andere Möglichkeit?

    Wenn es möglich ist, dann rufe Funktionen, die sofort nach dem laden des
    Scriptes gestartet werden sollen auch aus diesem heraus auf.

    Und wie kann ich sicher stellen, dass das Nachladen auch tatsächlich funktioniert hat?

    Das Script, das nachgeladen wird, kann z.b. eine Variable setzen, die du
    abfragst, eventuell kannst du auch ein Objekt, dass in diesem definiert wird
    auf Existenz prüfen.

    Auf Wiederlesen
    Detlef

    --
    - Wissen ist gut
    - Können ist besser
    - aber das Beste und Interessanteste ist der Weg dahin!
    1. Hallo Detlef,

      Natürlich, erst wenn die Resource wirklich geladen ist.

      Das könnte natürlich die Ursache sein. Ich hatte zwar in einem Versuch eine längere Verzögerung eingebaut, aber auch die könnte zu kurz gewesen sein.

      Notlösung!
      Du weißt nicht, wie lang die Verzögerung sein muss, da du kaum Einfluss
      darauf hast, wie lange das Nachladen benötigt. (z.b. könnte der Server
      kurzzeitig überlastet sein)

      Ich muss mehr oder weniger die gesamte Funktionalität des Fensters per JS realisieren und möchte dem Anwender jeweils die neueste Version zur Verfügung stellen, ohne dass er dafür aktiv werden muss.

      Das Script, das nachgeladen wird, kann z.b. eine Variable setzen, die du
      abfragst, eventuell kannst du auch ein Objekt, dass in diesem definiert wird
      auf Existenz prüfen.

      Ich hatte mir schon überlegt, die Funktionsbibliothek auf verschiedenen Servern abzulegen und in einer aus dem "Hauptscript" per setInterval() aufgerufenen Funktion das Laden zu prüfen und erst dann die Seite komplett anzuzeigen, wenn es von einem Server funktioniert hat.

      Ralf

  2. Hallo Ralf,

    Damit habe ich aber nun Probleme, weil ich den Code, der das Nachladen durchführen soll, erst zur Laufzeit in ein leeres Popup schreibe.

    warum lädst Du nach, statt gleich alles an benötigten Scripten (wie üblich) mittels <script type="text/javascript" src=""/> zu referenzieren?

    Grundsätzlich funktioniert das Laden dort auch (zwar nicht über onLoad, sondern direkt im Code), jedoch kann ich die geladenen Funktionen nicht sofort aufrufen, sondern sozusagen erst asynchron.

    Wie auch immer Du den Code "lädst", der eigentliche Aufruf sollte am Schluß der JavaScript-enthaltenden Datei erfolgen.

    Ich habe mir jetzt überlegt, in dem sofort ausgeführten Teil des Popups nur das Nachladen durchzuführen und die weitere Verarbeitung per setTimeout() zu verzögern.

    Das geht bei langsamen Verbindungen des Nutzers auch schief!

    Und wie kann ich sicher stellen, dass das Nachladen auch tatsächlich funktioniert hat? Es wird ja in jedem Fall ein Script-Element erzeugt, auch wenn der Code nicht geladen werden konnte.

    Definire am ende der JavaScript-enthaltenden Datei eine ID-Variable.

    Gruß aus Berlin!
    eddi

    --
    Wer Rechtschreibfehler findet, darf sie behalten.
    1. Hallo eddi,

      warum lädst Du nach, statt gleich alles an benötigten Scripten (wie üblich) mittels <script type="text/javascript" src=""/> zu referenzieren?

      Weil der Teil, welcher das Popup "initialisiert", beim Anwender liegt (lokal oder Webspace) und ich bei Änderungen nicht immer wieder neuen Code versenden möchte.
      Daher soll möglichst die gesamte Funktionalität nachgeladen werden.

      Das geht bei langsamen Verbindungen des Nutzers auch schief!

      Daher erzeuge ich zunächst ein SCRIPT Element und rufe dann per setInterval() eine Funktion auf, die eine Prüfung auf eine ID-Variable durchführt. Dies übergibt erst die Kontrolle, wenn die Variable gesetzt ist. Nach einer gewissen Zeit fordert die Routine dann auf, den Vorgang zu wiederholen und bricht ab.

      Im "Rohzustand" funktioniert das bereits.

      Ralf

      1. Re:

        warum lädst Du nach, statt gleich alles an benötigten Scripten (wie üblich) mittels <script type="text/javascript" src=""/> zu referenzieren?

        Weil der Teil, welcher das Popup "initialisiert", beim Anwender liegt (lokal oder Webspace) und ich bei Änderungen nicht immer wieder neuen Code versenden möchte.
        Daher soll möglichst die gesamte Funktionalität nachgeladen werden.

        Das geht bei langsamen Verbindungen des Nutzers auch schief!

        Daher erzeuge ich zunächst ein SCRIPT Element und rufe dann per setInterval() eine Funktion auf, die eine Prüfung auf eine ID-Variable durchführt. Dies übergibt erst die Kontrolle, wenn die Variable gesetzt ist. Nach einer gewissen Zeit fordert die Routine dann auf, den Vorgang zu wiederholen und bricht ab.

        Die Begründung geht doch an der Tatsache, daß Du mittels

        document.write('<script type="text/javascript" src="'+local_js+'"/>')
        document.write('<script type="text/javascript" src="http://www.domain.net/'+host_js+'"/>')

        genauso flexibel bist, wie Du es brauchst. Es gibt allerdings einige kleine Unterschiede: Du kannst Dir den ganzen Zirkus, denn Du jetzt zu veranstalten suchst, sparen. Das Nachladen von Code macht wirklich immer nur dann Sinn, wenn modulare Strukuren vorliegen und sollte immer erst als letztes in betracht gezogen werden. Denn insbesondere ältere Browser unterstützen das Nachladen nicht (Bsp: Opera >7.5).

        Gruß aus Berlin!
        eddi

        --
        Wer Rechtschreibfehler findet, darf sie behalten.
        1. Die Begründung geht doch an der Tatsache, daß Du mittels

          document.write('<script type="text/javascript" src="'+local_js+'"/>')
          document.write('<script type="text/javascript" src="http://www.domain.net/'+host_js+'"/>')

          genauso flexibel bist, wie Du es brauchst. Es gibt allerdings einige kleine Unterschiede: Du kannst Dir den ganzen Zirkus, denn Du jetzt zu veranstalten suchst, sparen. Das Nachladen von Code macht wirklich immer nur dann Sinn, wenn modulare Strukuren vorliegen und sollte immer erst als letztes in betracht gezogen werden. Denn insbesondere ältere Browser unterstützen das Nachladen nicht (Bsp: Opera >7.5).

          Rein aus technischer Sicht hast du natürlich Recht. Es soll aber nicht sofort offensichtlich sein, dass da noch weiterer Code ist.

          Außerdem geht es hier um eine sehr spezielle Anwendung, die aus einer genau definierten Umgebung heraus aufgerufen wird. Auf ältere Browser brauche ich keine Rücksicht zu nehmen. Es läuft im IE6 und FF1.5 und das ist ausreichend.

          Ralf

          Gruß aus Berlin!
          eddi

          1. Nundenn:

            Bei window.setTimeout() und den restlichen Informationen von Dir würde ich nicht wirklich ruhig schlafen können, da bedingt durch Netzwerk-/Serverauslastung etc. immer eine Überschreitung der vorhergesehenen Ladezeit auftreten kann. Es bliebe also nur window.setTimeout()/.setInterval() in einer Schleife, was aber auch nicht der wahre Jakob sein kann...

            Davon ausgehend, daß die nachgeladene Funktionalität mittels Events wie onClick abverlangt wird, hättest Du die Möglichkeit über node durch Setzen dieser Attribute in den entsprechenden HTML-Elementen auf das Prüfen des Ladezustandes zu verzichten. Gleichfalls wären auch die ID-Variablen überflüssig geworden, wenn die Attribute jeweils am Ende einer JS-Datei gesetzt würden.

            Das wäre das, was mir vorschwebt.

            Gruß aus Berlin!
            eddi

            --
            Wer Rechtschreibfehler findet, darf sie behalten.
            1. Hallo eddi,

              dann will noch etwas hinzugeben ...

              Es bliebe also nur window.setTimeout()/.setInterval() in einer Schleife, was aber auch nicht der wahre Jakob sein kann...

              Aber derzeit unter den gegebenen Umständen wohl die einzige Lösung.

              Aus Verfügbarkeitsgründen liegen die Routinen auf mehreren Servern. Ich hatte mich bisher noch nicht entschieden, ob ich grundsätzlich von allen Servern lade oder zunächst nur vom bevorzugten Server.

              Ich würde gern letzterem den Vorzug geben und dann wäre einen "statische" Lösung m.E. nicht mehr möglich.
              Es schadet zwar nicht, die Routinen mehrfach zu laden, aber es gefällt mir nicht wirklich.

              Davon ausgehend, daß die nachgeladene Funktionalität mittels Events wie onClick abverlangt wird, hättest Du die Möglichkeit über node durch Setzen dieser Attribute in den entsprechenden HTML-Elementen auf das Prüfen des Ladezustandes zu verzichten. Gleichfalls wären auch die ID-Variablen überflüssig geworden, wenn die Attribute jeweils am Ende einer JS-Datei gesetzt würden.

              Es soll i.W. die gesamte Funktionalität in den geladenen Routinen untergebracht werden. Und dazu gehören auch Teile, die sofort und ohne Ereignis ausgeführt werden müssen (wie z.B. die Darstellung der initialen Ansicht). Ohne eine Prüfung komme ich also nicht aus.

              Das wäre das, was mir vorschwebt.

              Und ich muss von den Gegebenheiten ausgehen, die natürlich nur mir im Detail bekannt sind ;)

              Ralf