Wie können Sie eine JavaScript-Datei zuverlässig und dynamisch laden? Dies kann verwendet werden, um ein Modul oder eine Komponente zu implementieren, bei deren Initialisierung die Komponente bei Bedarf alle erforderlichen JavaScript-Bibliotheksskripte dynamisch lädt.
Der Client, der die Komponente verwendet, muss nicht alle Bibliotheksskriptdateien laden (und <script>
Tags manuell in seine Webseite einfügen ), die diese Komponente implementieren - nur die 'Haupt'-Komponentenskriptdatei.
Wie erreichen Mainstream-JavaScript-Bibliotheken dies (Prototype, jQuery usw.)? Führen diese Tools mehrere JavaScript-Dateien zu einer einzigen weiterverteilbaren Build-Version einer Skriptdatei zusammen? Oder laden sie zusätzliche 'Bibliotheksskripte' dynamisch?
Eine Ergänzung zu dieser Frage: Gibt es eine Möglichkeit, das Ereignis zu behandeln, nachdem eine dynamisch enthaltene JavaScript-Datei geladen wurde? Prototyp hat document.observe
für dokumentweite Ereignisse. Beispiel:
document.observe("dom:loaded", function() {
// initially hide all containers for tab content
$$('div.tabcontent').invoke('hide');
});
Was sind die verfügbaren Ereignisse für ein Skriptelement?
quelle
Antworten:
Sie können dynamische Skript-Tags schreiben (mit Prototype ):
Das Problem hierbei ist, dass wir nicht wissen, wann die externe Skriptdatei vollständig geladen ist.
Wir wollen oft unseren abhängigen Code in der nächsten Zeile und schreiben gerne etwas wie:
Es gibt eine clevere Möglichkeit, Skriptabhängigkeiten ohne Rückrufe einzufügen. Sie müssen das Skript einfach über eine synchrone AJAX-Anforderung abrufen und das Skript auf globaler Ebene bewerten.
Wenn Sie Prototype verwenden, sieht die Script.load-Methode folgendermaßen aus:
quelle
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)web.archive.org
.Es gibt keinen Import / Include / Require in Javascript, aber es gibt zwei Möglichkeiten, um das zu erreichen, was Sie wollen:
1 - Sie können es mit einem AJAX-Aufruf laden und dann eval verwenden.
Dies ist der einfachste Weg, aber aufgrund der Javascript-Sicherheitseinstellungen auf Ihre Domain beschränkt. Die Verwendung von eval öffnet die Tür für Fehler und Hacks.
2 - Fügen Sie ein Skript-Tag mit der Skript-URL im HTML hinzu.
Auf jeden Fall der beste Weg. Sie können das Skript sogar von einem fremden Server laden, und es ist sauber, wenn Sie den Browser-Parser zum Auswerten des Codes verwenden. Sie können das Tag im Kopf der Webseite oder am unteren Rand des Körpers platzieren.
Beide Lösungen werden hier diskutiert und veranschaulicht.
Nun gibt es ein großes Problem, über das Sie Bescheid wissen müssen. Dies bedeutet, dass Sie den Code remote laden. Moderne Webbrowser laden die Datei und führen Ihr aktuelles Skript weiter aus, da sie alles asynchron laden, um die Leistung zu verbessern.
Wenn Sie diese Tricks direkt verwenden, können Sie Ihren neu geladenen Code in der nächsten Zeile, nachdem Sie ihn zum Laden aufgefordert haben, nicht verwenden, da er noch geladen wird.
EG: my_lovely_script.js enthält MySuperObject
Dann laden Sie die Seite neu und treffen F5. Und es funktioniert! Verwirrend...
Was tun?
Nun, Sie können den Hack verwenden, den der Autor in dem Link vorschlägt, den ich Ihnen gegeben habe. Zusammenfassend lässt sich sagen, dass Personen, die es eilig haben, mit en event eine Rückruffunktion ausführen, wenn das Skript geladen wird. So können Sie den gesamten Code mithilfe der Remote-Bibliothek in die Rückruffunktion einfügen. Z.B :
Dann schreiben Sie den Code, den Sie verwenden möchten, nachdem das Skript in eine Lambda-Funktion geladen wurde:
Dann führen Sie das alles aus:
OK ich habe es. Aber es ist ein Schmerz, all dieses Zeug zu schreiben.
In diesem Fall können Sie wie immer das fantastische kostenlose jQuery-Framework verwenden, mit dem Sie in einer Zeile genau dasselbe tun können:
quelle
Ich habe kürzlich mit jQuery eine viel weniger komplizierte Version verwendet :
Es funktionierte hervorragend in jedem Browser, in dem ich es getestet habe: IE6 / 7, Firefox, Safari, Opera.
Update: jQuery-less Version:
quelle
$.getScript
. Siehe meine Antwort.Ich habe im Grunde das Gleiche getan wie Sie, Adam, aber mit einer geringfügigen Änderung, um sicherzustellen, dass ich an die Kopfmarke angehängt habe, um die Arbeit zu erledigen. Ich habe einfach eine Include-Funktion (Code unten) erstellt, um sowohl Skript- als auch CSS-Dateien zu verarbeiten.
Diese Funktion überprüft auch, ob das Skript oder die CSS-Datei noch nicht dynamisch geladen wurde. Es wird nicht nach handcodierten Werten gesucht, und es gab möglicherweise einen besseren Weg, dies zu tun, aber es hat den Zweck erfüllt.
quelle
eine weitere tolle Antwort
https://stackoverflow.com/a/950146/671046
quelle
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Hier ist ein Beispielcode, den ich gefunden habe ... hat jemand einen besseren Weg?
quelle
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Wenn Sie jQuery bereits geladen haben, sollten Sie $ .getScript verwenden .
Dies hat gegenüber den anderen Antworten hier den Vorteil, dass Sie über eine integrierte Rückruffunktion verfügen (um sicherzustellen, dass das Skript geladen wird, bevor der abhängige Code ausgeführt wird) und das Caching steuern können.
quelle
Wenn Sie ein SYNC- Skript laden möchten , müssen Sie Skripttext direkt zum HTML HEAD-Tag hinzufügen. Wenn Sie es als hinzufügen, wird ein ASYNC-Ladevorgang ausgelöst . Verwenden Sie XHR, um Skripttext synchron aus einer externen Datei zu laden. Unten ein kurzes Beispiel (es werden Teile anderer Antworten in diesem und anderen Beiträgen verwendet):
quelle
Ich denke, nur das Hinzufügen des Skripts zum Textkörper wäre einfacher als das Hinzufügen zum letzten Knoten auf der Seite. Wie wäre es damit:
quelle
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Ich habe noch eine andere Lösung verwendet, die ich im Internet gefunden habe ... diese befindet sich unter creativecommons und prüft, ob die Quelle enthalten war, bevor die Funktion aufgerufen wird ...
Die Datei finden Sie hier: include.js
quelle
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Ich habe gerade etwas über eine großartige Funktion in YUI 3 erfahren (zum Zeitpunkt des Schreibens in der Vorschau-Version verfügbar). Sie können problemlos Abhängigkeiten zu YUI-Bibliotheken und zu "externen" Modulen (was Sie suchen) einfügen, ohne zu viel Code: YUI Loader .
Es beantwortet auch Ihre zweite Frage bezüglich der aufgerufenen Funktion, sobald das externe Modul geladen ist.
Beispiel:
Hat für mich perfekt funktioniert und hat den Vorteil, Abhängigkeiten zu verwalten. In der YUI-Dokumentation finden Sie ein Beispiel für den YUI 2-Kalender .
quelle
Es gibt einen neuen vorgeschlagenen ECMA-Standard namens Dynamic Import , der kürzlich in Chrome und Safari integriert wurde.
quelle
Die Technik, die wir bei der Arbeit verwenden, besteht darin, die Javascript-Datei mithilfe einer AJAX-Anforderung anzufordern und dann die Rückgabe auszuwerten (). Wenn Sie die Prototypbibliothek verwenden, unterstützen sie diese Funktionalität in ihrem Ajax.Request-Aufruf.
quelle
jquery hat dies für mich mit der Funktion .append () behoben - damit wurde das komplette jquery ui-Paket geladen
Zu verwenden - im Kopf Ihres HTML / PHP / etc, nachdem Sie jquery.js importiert haben, würden Sie einfach diese eine Datei so einfügen, dass sie in die gesamte Bibliothek geladen wird, indem Sie sie an den Kopf anhängen ...
quelle
Halten Sie es schön, kurz, einfach und wartbar! :]
Dieser Code ist nur ein kurzes Funktionsbeispiel , das könnte zusätzliche Feature - Funktionalität für die volle Unterstützung auf allen (oder gegeben) Plattform erfordern.
quelle
Der Import dynamischer Module landete in Firefox 67+ .
Mit Fehlerbehandlung:
Es funktioniert auch für alle Arten von Nicht-Modul-Bibliotheken. In diesem Fall ist die Bibliothek auf dem Fensterobjekt verfügbar, wie bisher, aber nur auf Anfrage, was sehr schön ist.
Beispiel mit suncalc.js : Auf dem Server muss CORS aktiviert sein , damit dies funktioniert!
https://caniuse.com/#feat=es6-module-dynamic-import
quelle
Es gibt Skripte, die speziell für diesen Zweck entwickelt wurden.
yepnope.js ist in Modernizr und lab.js integriert ist eine optimierte (aber weniger benutzerfreundliche Version).
Ich würde nicht empfehlen, dies über eine große Bibliothek wie jquery oder prototype zu tun - da einer der Hauptvorteile eines Skriptladeprogramms die Möglichkeit ist, Skripte frühzeitig zu laden, sollten Sie nicht warten müssen, bis jquery und alle Ihre dom-Elemente vor dem Laden geladen werden Führen Sie eine Überprüfung durch, um festzustellen, ob Sie ein Skript dynamisch laden möchten.
quelle
Ich habe ein einfaches Modul geschrieben, das das Importieren / Einschließen von Modulskripten in JavaScript automatisiert. Probieren Sie es aus und ersparen Sie sich Feedback! :) Eine ausführliche Erläuterung des Codes finden Sie in diesem Blog-Beitrag: http://stamat.wordpress.com/2013/04/12/javascript-require-import-include-modules/
quelle
Ich bin in all diesen Beispielen verloren, aber heute musste ich eine externe .js von meiner Haupt-.js laden und ich tat dies:
quelle
Hier ist eine einfache mit Rückruf- und IE-Unterstützung:
quelle
Ich weiß, dass meine Antwort auf diese Frage etwas spät ist, aber hier ist ein großartiger Artikel auf www.html5rocks.com - Tauchen Sie tief in das trübe Wasser des Ladens von Skripten ein .
In diesem Artikel wird der Schluss gezogen, dass in Bezug auf die Browserunterstützung der beste Weg zum dynamischen Laden von JavaScript-Dateien ohne Blockierung des Renderns von Inhalten der folgende Weg ist:
Wenn Sie vier Skripte mit dem Namen haben
script1.js, script2.js, script3.js, script4.js
, können Sie async = false anwenden :Jetzt sagt Spec : Gemeinsam herunterladen, in der richtigen Reihenfolge ausführen, sobald alle heruntergeladen sind.
Firefox <3.6, Opera sagt: Ich habe keine Ahnung, was dieses "asynchrone" Ding ist, aber es passiert einfach so, dass ich über JS hinzugefügte Skripte in der Reihenfolge ausführe, in der sie hinzugefügt wurden.
Safari 5.0 sagt: Ich verstehe "async", verstehe es aber nicht, es mit JS auf "false" zu setzen. Ich werde Ihre Skripte ausführen, sobald sie landen, in welcher Reihenfolge auch immer.
IE <10 sagt: Keine Ahnung von "async", aber es gibt eine Problemumgehung mit "onreadystatechange".
Alles andere sagt: Ich bin dein Freund, wir werden das nach dem Buch machen.
Nun der vollständige Code mit IE <10 Workaround:
Ein paar Tricks und Minimierungen später sind es 362 Bytes
quelle
Etwas wie das...
quelle
Hier ein einfaches Beispiel für eine Funktion zum Laden von JS-Dateien. Relevante Punkte:
$.ajax
oder$.getScript
Sie können Nonces verwenden, um Probleme mit CSP zu lösenunsafe-inline
. Nutzen Sie einfach die Eigenschaftscript.nonce
Jetzt benutzt du es einfach von
quelle
Ein absurder Einzeiler für diejenigen, die denken, dass das Laden einer js-Bibliothek nicht mehr als eine Codezeile erfordern sollte: P.
Wenn es sich bei dem zu importierenden Skript um ein Modul handelt, können Sie die
import(...)
Funktion natürlich verwenden .quelle
Mit Promises können Sie es so vereinfachen. Ladefunktion:
Verwendung (asynchron / warten):
Verwendung (Versprechen):
HINWEIS: Es gab eine ähnliche Lösung, die jedoch nicht überprüft, ob das Skript bereits geladen ist, und das Skript jedes Mal lädt. Dieser überprüft die src-Eigenschaft.
quelle
Alle wichtigen Javascript-Bibliotheken wie jscript, prototype und YUI unterstützen das Laden von Skriptdateien. In YUI können Sie beispielsweise nach dem Laden des Kerns die folgenden Schritte ausführen, um das Kalendersteuerelement zu laden
quelle
Ich habe einige der oben genannten Beiträge mit einem funktionierenden Beispiel optimiert. Hier können wir auch css und js im selben Array angeben.
quelle
Für diejenigen unter Ihnen, die Einzeiler lieben:
Möglicherweise erhalten Sie einen Fehler wie:
In diesem Fall können Sie auf Folgendes zurückgreifen:
quelle