2009-05-25 9 views
3

Ich verwende JQuery, um dynamisch Skript-Tags in den Body-Tab einer Webseite zu injizieren. Ich habe etwas wie:Wie man Javascript-Dateien dynamisch lädt und sie sofort benutzt?

function addJS(url) { 
    $("body").append('<script type="text/javascript" src='+url+'></script>'); 
} 

Ich füge mehrere Skripte auf diese Weise, und versuche, sie direkt danach zu verwenden. Z. B:

lib.js

function core() {...} 
alert("I'am here !"); 

Init.js

addJS("lib.js"); 
c = new core(); 

test.html

<html> 
    <head> 
    <title>test</title>   
    <script type="text/javascript" src="init.js"></script> 
    </head> 
    <body> 
    Hello 
    </body> 
</html> 

Laden test.html pop s up "Ich bin hier" und endet dann mit einem Fehler "Core ist nicht definiert". Natürlich werden beide JS-Dateien zusammengefügt, damit sie perfekt funktionieren.

Ich bekomme es einfach nicht o_O.

EDIT

ich vereinfacht dieses Beispiel, aber Jeff Antwort gab mir zu verstehen, dass es ein Fehler war. Also hier sind einige Details:

init.js ist nicht im Kopf von test.html, wenn es neu zu laden, weil ich es mit einem Code injected auf einem Bookmarklet injizieren.

Die eigentliche Ausführungsprozess ist die folgende:

reload test.html> das Bookmarklet laufen> jquery und Init.js eingefügt> lib.js eingeführt wird

Sorry für die Verwirrung.

EDIT 2

Jetzt habe ich die Lösung für mein Problem (das war schnell :-)), aber ich bin immer noch auf die Antwort auf meine Frage interessiert. Warum geht das schief?

Antwort

3

Sie erhalten den Fehler "Kern ist nicht definiert", weil die Skripte asynchron geladen werden. Das bedeutet, dass Ihr Browser lib.js im Hintergrund lädt und weiterhin init.js ausführt und dann "new core()" vor dem Laden von lib.js findet.

Die getScript Funktion einen Rückruf hat, der ausgelöst wird, nachdem das Skript fertig geladen:

$.getScript('lib.js', function() { 
    var c = new core(); 
}); 
1

Beachten Sie, dass Ihre addJS-Funktion an das Ende des body-Elements angehängt ist.

Da Browser werden Skripte ausgeführt, wie sie in der HTML-Quelle erscheinen,

c = new core() 

laufen, bevor Sie lib.js Skript (am Ende des Körperelements) geladen wird.

Ich würde empfehlen, c = new core() zu verschieben; in das $ (document) .ready (function() {...}); oder in ein Skriptelement NACH dem Body-Tag.

+0

Ok, ich werde die Frage bearbeiten, weil Sie einen Punkt bekommen, aber dies hier nicht Appy. Ich habe mein Beispiel vereinfacht, aber mir ist klar, dass sich vieles ändert. Tatsächlich wurde die test.html bereits geladen, da ich init.js mit einem Bookmarklet injiziere. –

5

jQuery hat diese Funktionalität eingebaut mit getScript.

+0

Meine Güte, es wird so nützlich sein. Danke! Ich klicke nicht auf "gelöst", weil ich gerne verstehen würde, warum mein Weg falsch ist. –

1

IMO, das Anfügen des Skript-Tags an das Ende des Dokuments, um ein Skript zu laden, ist ziemlich unansehnlich.Grund:

  1. Sie vertrauen darauf, dass der Browser das Skript automatisch abruft und lädt.
  2. Sie haben keine Möglichkeit herauszufinden, ob das Skript geladen wird, geladen würde entweder, oder wenn es einen Fehler aufgetreten ist (vielleicht 404?)

Der geeignete Weg $ .getScript() zu verwenden, um sein, oder für ein feinkörnigeres Steuerelement, holen Sie sich die Skriptdatei mit $ .ajax() und verwenden Sie eval().

Die zweite Methode hat jedoch einige Probleme: Wenn Sie eval() innerhalb einer Funktion aufgerufen haben, ist das Skript außerhalb dieser Funktion nicht verfügbar! Dies mietet Problemumgehungen ...

aber warum zu stören! benutze $ .getScript() und komm vorbei :)

cheers, jrh.

+0

Siehe den Kommentar für Paolo Bergantino. –

+0

Aber eigentlich habe ich einen Weg zu nein, wenn das Skript mit Firebugf und console.log geladen wird (und es ist). Jedenfalls sind die js-Dateien tatsächlich PHP-Dateien, die die js on the fly generieren, und sie haben auch ein Logging-System, so dass ich weiß, dass ich keinen 404 treffe. Aber Sie haben Recht, es zu erwähnen. –

+0

Ja, Firebug kann das für Sie tun, aber nur zur Entwicklungszeit. Nicht zur Laufzeit. – jrharshath

1

Als Reaktion darauf, warum Ihr Code fehlschlägt: Das Hinzufügen eines Skript-Tags zum Body blockiert die weitere Skriptausführung nicht. Dein Code fügt es hinzu, wodurch der Downloadvorgang des Browsers gestartet wird. In der Zwischenzeit versucht Ihr Skript, core() aufzurufen, das nicht existiert, weil lib.js den Download noch nicht beendet hat. jQuery funktioniert, weil es wartet, bis das Skript den Download beendet hat, bevor es die Callback-Funktion ausführt.