Wie kann ich ein <script src="https://remote.com/"></script>
Element in meine Seite einfügen, auf die Ausführung warten und dann die von ihm definierten Funktionen verwenden?
Zu Ihrer Information: In meinem Fall führt das Skript in seltenen Fällen eine Kreditkartenverarbeitung durch, daher möchte ich es nicht immer einschließen. Ich möchte es schnell einschließen, wenn der Benutzer ein Dialogfeld zum Ändern der Kreditkartenoptionen öffnet und ihm dann die neuen Kreditkartenoptionen sendet.
Für weitere Details bearbeiten: Ich habe keinen Zugriff auf das Remote-Skript.
javascript
Riley Lark
quelle
quelle
Antworten:
Sie können Google Analytics oder die Methode von Facebook verwenden:
(function(d, script) { script = d.createElement('script'); script.type = 'text/javascript'; script.async = true; script.onload = function(){ // remote script has loaded }; script.src = 'http://www.google-analytics.com/ga.js'; d.getElementsByTagName('head')[0].appendChild(script); }(document));
AKTUALISIEREN:
Unten finden Sie die neue Facebook-Methode. Es basiert auf einem vorhandenen Skript-Tag anstelle von
<head>
:(function(d, s, id){ var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)){ return; } js = d.createElement(s); js.id = id; js.onload = function(){ // remote script has loaded }; js.src = "//connect.facebook.net/en_US/sdk.js"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));
facebook-jssdk
durch Ihre eindeutige Skript-ID, um zu vermeiden, dass sie mehrmals angehängt wird.quelle
script.onload
oder zu verwendenjs.onload
, würde ich demload
Ereignis einen Ereignis-Listener hinzufügen . stackoverflow.com/questions/15564029/…script
gegenüber dem Anhängen an denhead
? Der Nachteil, den ich beim Anhängen anscript
s sehe, ist, wenn es keine zum Anhängen gibt, würde es brechen.d.getElementsByTagName(s)[0]
unter dieif
Prüfung verschoben werden kann , um sich eine DOM-Abfrage zu sichern, wenn das Skript bereits vorhanden ist.Gleiche Methode mit Ereignis-Listenern und ES2015-Konstrukten:
function injectScript(src) { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = src; script.addEventListener('load', resolve); script.addEventListener('error', e => reject(e.error)); document.head.appendChild(script); }); } injectScript('https://example.com/script.js') .then(() => { console.log('Script loaded!'); }).catch(error => { console.error(error); });
quelle
Dies ist eine Möglichkeit, eine Liste von Skripten dynamisch zu laden und synchron auszuführen. Sie müssen jedes Skript-Tag in das DOM einfügen und sein asynchrones Attribut explizit auf false setzen:
script.async = false;
Skripte, die in das DOM eingefügt wurden, werden standardmäßig asynchron ausgeführt. Sie müssen daher das asynchrone Attribut manuell auf false setzen, um dies zu umgehen.
Beispiel
<script> (function() { var scriptNames = [ "https://code.jquery.com/jquery.min.js", "example.js" ]; for (var i = 0; i < scriptNames.length; i++) { var script = document.createElement('script'); script.src = scriptNames[i]; script.async = false; // This is required for synchronous execution document.head.appendChild(script); } // jquery.min.js and example.js will be run in order and synchronously })(); </script> <!-- Gotcha: these two script tags may still be run before `jquery.min.js` and `example.js` --> <script src="example2.js"></script> <script>/* ... */<script>
Verweise
quelle
so etwas sollte den Trick machen:
(function() { // Create a new script node var script = document.createElement("script"); script.type = "text/javascript"; script.onload = function() { // Cleanup onload handler script.onload = null; // do stuff with the loaded script! } // Add the script to the DOM (document.getElementsByTagName( "head" )[ 0 ]).appendChild( script ); // Set the `src` to begin transport script.src = "https://remote.com/"; })();
hoffentlich hilft das! Prost.
quelle
Dynamisch
import()
Mit dem dynamischen Import können Sie jetzt Module laden und warten, bis sie ausgeführt werden. So einfach ist das:
import("http://example.com/module.js").then(function(module) { alert("module ready"); });
Wenn das Modul bereits geladen und ausgeführt wurde, wird es nicht erneut geladen und ausgeführt, aber das von zurückgegebene Versprechen
import
wird weiterhin aufgelöst.Beachten Sie, dass die Datei als Modul und nicht nur als Skript geladen wird. Module werden im strengen Modus ausgeführt und im Modulbereich geladen. Dies bedeutet, dass Variablen nicht automatisch global gemacht werden, wie sie es in normal geladenen Skripten sind. Verwenden Sie das
export
Schlüsselwort in einem Modul, um eine Variable für andere Module oder Skripte freizugeben.Verweise:
import
import()
quelle
Erstellen Sie einen Lader
Sie können das Skript ordnungsgemäß in einen Loader einfügen.
Beachten Sie, dass die Ausführung der dynamisch geladenen Skripte normalerweise nach statisch geladenen Skripten (dh
<script src="My_script.js"></script>
) erfolgt (die Reihenfolge der Injektion im DOM garantiert nicht das Gegenteil):zB loader.js:
function appendScript(url){ let script = document.createElement("script"); script.src = url; script.async = false //IMPORTANT /*Node Insertion Point*/.appendChild(script); } appendScript("my_script1.js"); appendScript("my_script2.js");
my_script1.js
wird effektiv vorher ausgeführtmy_script2.js
(hilfreich, wenn Abhängigkeiten von vorhandenmy_script2.js
sindmy_script1.js
)Beachten Sie, dass dies wichtig ist,
script.async = false
da dynamisch geladene Skripteasync = true
standardmäßigasync
die Reihenfolge des Ladens nicht gewährleisten.quelle
Hier ist meine angepasste Version, basierend auf der Antwort von Frank:
static async importScript(src, expressionToEvaluateAndReturn){ return new Promise((resolve, reject) => { const script = document.createElement('script'); script.async = true; script.src = src; script.addEventListener('load', (event)=>{ if(expressionToEvaluateAndReturn){ try{ let result = eval(expressionToEvaluateAndReturn); resolve(result); } catch(error){ reject(error); } } else { resolve(); } }); script.addEventListener('error', () => reject('Error loading script "' + src + '"')); script.addEventListener('abort', () => reject('Script loading aborted for "' + src + '"')); document.head.appendChild(script); }); }
Anwendungsbeispiel:
let d3 = await importScript('/bower_components/d3/d3.min.js','d3') .catch(error => { console.log(error); throw error; });
quelle