Frage

Wie können Sie eine JavaScript-Datei zuverlässig und dynamisch laden?Dies kann verwendet werden, um ein Modul oder eine Komponente zu implementieren, die bei der Initialisierung der Komponente alle benötigten JavaScript-Bibliotheksskripte bei Bedarf dynamisch lädt.

Der Client, der die Komponente verwendet, muss nicht alle Bibliotheksskriptdateien laden (und manuell einfügen). <script> Tags in ihre Webseite einfügen), die diese Komponente implementieren – nur die Skriptdatei der „Hauptkomponente“.

Wie erreichen gängige JavaScript-Bibliotheken dies (Prototype, jQuery usw.)? Führen diese Tools mehrere JavaScript-Dateien zu einer einzigen weiterverteilbaren „Build“-Version einer Skriptdatei zusammen?Oder führen sie ein dynamisches Laden zusätzlicher „Bibliotheks“-Skripte durch?

Eine Ergänzung zu dieser Frage: Gibt es eine Möglichkeit, das Ereignis zu behandeln, nachdem eine dynamisch eingebundene 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');
});

Welche Ereignisse sind für ein Skriptelement verfügbar?

War es hilfreich?

Lösung

Sie können dynamische Skript-Tags schreiben (mit Prototyp):

new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});

Das Problem hierbei ist, dass wir es nicht wissen Wann Die externe Skriptdatei ist vollständig geladen.

Wir wollen unseren abhängigen Code oft in der nächsten Zeile haben und schreiben gerne so etwas wie:

if (iNeedSomeMore) {
    Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
    myFancyMethod(); // cool, no need for callbacks!
}

Es gibt eine intelligente Möglichkeit, Skriptabhängigkeiten einzufügen, ohne dass Rückrufe erforderlich sind.Sie müssen das Skript einfach über a ziehen synchrone AJAX-Anfrage und bewerten Sie das Skript auf globaler Ebene.

Wenn Sie Prototype verwenden, sieht die Script.load-Methode folgendermaßen aus:

var Script = {
    _loadedScripts: [],
    include: function(script) {
        // include script only once
        if (this._loadedScripts.include(script)) {
            return false;
        }
        // request file synchronous
        var code = new Ajax.Request(script, {
            asynchronous: false,
            method: "GET",
            evalJS: false,
            evalJSON: false
        }).transport.responseText;
        // eval code on global level
        if (Prototype.Browser.IE) {
            window.execScript(code);
        } else if (Prototype.Browser.WebKit) {
            $$("head").first().insert(Object.extend(
                new Element("script", {
                    type: "text/javascript"
                }), {
                    text: code
                }
            ));
        } else {
            window.eval(code);
        }
        // remember included script
        this._loadedScripts.push(script);
    }
};

Andere Tipps

In Javascript gibt es kein Import/Include/Require, aber es gibt zwei Hauptwege, 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 ist er auf Ihre Domain beschränkt und die Verwendung von eval öffnet Fehlern und Hacks Tür und Tor.

2 – Fügen Sie im HTML ein Skript-Tag mit der Skript-URL hinzu.

Auf jeden Fall der beste Weg.Sie können das Skript sogar von einem fremden Server laden und es ist sauber, da Sie den Browser-Parser zum Auswerten des Codes verwenden.Sie können das Tag im Kopf der Webseite oder am Ende des Hauptteils platzieren.

Beide Lösungen werden hier besprochen und veranschaulicht.

Nun gibt es ein großes Problem, über das Sie Bescheid wissen müssen.Dies bedeutet, dass Sie den Code aus der Ferne laden.Moderne Webbrowser laden die Datei und führen Ihr aktuelles Skript weiterhin aus, da sie alles asynchron laden, um die Leistung zu verbessern.

Wenn Sie diese Tricks direkt anwenden, bedeutet dies, dass Sie Ihren neu geladenen Code in der nächsten Zeile, nachdem Sie ihn zum Laden aufgefordert haben, nicht verwenden können, da er noch geladen wird.

Z.B :my_lovely_script.js enthält MySuperObject

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

Dann laden Sie die Seite neu, indem Sie F5 drücken.Und es funktioniert!Verwirrend...

Was also dagegen 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 er für Leute, die es eilig haben, en event verwendet, um eine Rückruffunktion auszuführen, wenn das Skript geladen wird.Sie können also den gesamten Code mithilfe der Remote-Bibliothek in die Rückruffunktion einfügen.Z.B :

function loadScript(url, callback)
{
    // adding the script tag to the head as suggested before
   var head = document.getElementsByTagName('head')[0];
   var script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = url;

   // then bind the event to the callback function 
   // there are several events for cross browser compatibility
   script.onreadystatechange = callback;
   script.onload = callback;

   // fire the loading
   head.appendChild(script);
}

Dann schreiben Sie den Code, den Sie verwenden möchten, NACHDEM das Skript in eine Lambda-Funktion geladen wurde:

var myPrettyCode = function() {
    // here, do what ever you want
};

Dann führen Sie das alles aus:

loadScript("my_lovely_script.js", myPrettyCode);

OK ich habe es.Aber es ist mühsam, all dieses Zeug zu schreiben.

Nun, in diesem Fall können Sie wie immer das fantastische kostenlose jQuery-Framework verwenden, mit dem Sie genau das Gleiche in einer Zeile tun können:

$.getScript("my_lovely_script.js", function() {
    alert("Script loaded and executed.");
    // here you can use anything you defined in the loaded script
});

Ich habe ein verwendet viel weniger komplizierte Version in letzter Zeit mit jQuery:

<script src="scripts/jquery.js"></script>
<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  var $head = $("head");
  for (var i = 0; i < js.length; i++) {
    $head.append("<script src=\"" + js[i] + "\"></scr" + "ipt>");
  }
</script>

Es hat in jedem Browser, in dem ich es getestet habe, großartig funktioniert:IE6/7, Firefox, Safari, Opera.

Aktualisieren: jQuery-lose Version:

<script>
  var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
  for (var i = 0, l = js.length; i < l; i++) {
    document.getElementsByTagName("head")[0].innerHTML += ("<script src=\"" + js[i] + "\"></scr" + "ipt>");
  }
</script>

Ich habe im Grunde das Gleiche gemacht wie du, Adam, aber mit einer kleinen Modifikation, um sicherzustellen, dass ich das Head-Tag anfüge, 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 prüft auch, ob das Skript oder die CSS-Datei nicht bereits dynamisch geladen wurde.Es wird nicht nach handcodierten Werten gesucht und es hätte vielleicht einen besseren Weg gegeben, dies zu tun, aber es hat seinen Zweck erfüllt.

function include( url, type ){
    // First make sure it hasn't been loaded by something else.
    if( Array.contains( includedFile, url ) )
        return;

    // Determine the MIME-type
    var jsExpr = new RegExp( "js$", "i" );
    var cssExpr = new RegExp( "css$", "i" );
    if( type == null )
        if( jsExpr.test( url ) )
            type = 'text/javascript';
        else if( cssExpr.test( url ) )
            type = 'text/css';

    // Create the appropriate element.
    var tag = null;
    switch( type ){
        case 'text/javascript' :
            tag = document.createElement( 'script' );
            tag.type = type;
            tag.src = url;
            break;
        case 'text/css' :
            tag = document.createElement( 'link' );
            tag.rel = 'stylesheet';
            tag.type = type;
            tag.href = url;
            break;
    }

    // Insert it to the <head> and the array to ensure it is not
    // loaded again.
    document.getElementsByTagName("head")[0].appendChild( tag );
    Array.add( includedFile, url );
}

noch eine tolle Antwort

$.getScript("my_lovely_script.js", function(){


   alert("Script loaded and executed.");
  // here you can use anything you defined in the loaded script

 });

https://stackoverflow.com/a/950146/671046

Hier ist ein Beispielcode, den ich gefunden habe ...Hat jemand einen besseren Weg?

  function include(url)
  {
    var s = document.createElement("script");
    s.setAttribute("type", "text/javascript");
    s.setAttribute("src", url);
    var nodes = document.getElementsByTagName("*");
    var node = nodes[nodes.length -1].parentNode;
    node.appendChild(s);
  }

Wenn Sie jQuery bereits geladen haben, sollten Sie es verwenden $.getScript.

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 Sie das Caching steuern können.

Hat jemand einen besseren Weg?

Ich denke, dass es einfacher wäre, das Skript einfach zum Hauptteil hinzuzufügen, als es zum letzten Knoten auf der Seite hinzuzufügen.Wie wäre es damit:

function include(url) {
  var s = document.createElement("script");
  s.setAttribute("type", "text/javascript");
  s.setAttribute("src", url);
  document.body.appendChild(s);
}

Ich habe noch eine andere Lösung verwendet, die ich im Internet gefunden habe ...Dieses ist unter Creative Commons und es prüft, ob die Quelle vor dem Aufruf der Funktion enthalten war ...

Die Datei finden Sie hier: include.js

/** include - including .js files from JS - bfults@gmail.com - 2005-02-09
 ** Code licensed under Creative Commons Attribution-ShareAlike License 
 ** http://creativecommons.org/licenses/by-sa/2.0/
 **/              
var hIncludes = null;
function include(sURI)
{   
  if (document.getElementsByTagName)
  {   
    if (!hIncludes)
    {
      hIncludes = {}; 
      var cScripts = document.getElementsByTagName("script");
      for (var i=0,len=cScripts.length; i < len; i++)
        if (cScripts[i].src) hIncludes[cScripts[i].src] = true;
    }
    if (!hIncludes[sURI])
    {
      var oNew = document.createElement("script");
      oNew.type = "text/javascript";
      oNew.src = sURI;
      hIncludes[sURI]=true;
      document.getElementsByTagName("head")[0].appendChild(oNew);
    }
  }   
} 

Habe gerade von einer tollen Funktion erfahren YUI 3 (zum Zeitpunkt des Schreibens als Vorschauversion verfügbar).Sie können ganz einfach 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 Funktion, die aufgerufen wird, sobald das externe Modul geladen wird.

Beispiel:

YUI({
    modules: {
        'simple': {
            fullpath: "http://example.com/public/js/simple.js"
        },
        'complicated': {
            fullpath: "http://example.com/public/js/complicated.js"
            requires: ['simple']  // <-- dependency to 'simple' module
        }
    },
    timeout: 10000
}).use('complicated', function(Y, result) {
    // called as soon as 'complicated' is loaded
    if (!result.success) {
        // loading failed, or timeout
        handleError(result.msg);
    } else {
        // call a function that needs 'complicated'
        doSomethingComplicated(...);
    }
});

Hat bei mir perfekt funktioniert und bietet den Vorteil, dass Abhängigkeiten verwaltet werden können.Weitere Informationen finden Sie in der YUI-Dokumentation Beispiel mit YUI 2 Kalender.

Wenn Sie ein wollen SYNC Beim Laden des Skripts müssen Sie den Skripttext direkt zum HTML-HEAD-Tag hinzufügen.Wenn Sie es als hinzufügen, wird ein ausgelöst ASYNC Belastung.Um Skripttext synchron aus einer externen Datei zu laden, verwenden Sie XHR.Nachfolgend ein kurzes Beispiel (es werden Teile anderer Antworten in diesem und anderen Beiträgen verwendet):

/*sample requires an additional method for array prototype:*/

if (Array.prototype.contains === undefined) {
Array.prototype.contains = function (obj) {
    var i = this.length;
    while (i--) { if (this[i] === obj) return true; }
    return false;
};
};

/*define object that will wrap our logic*/
var ScriptLoader = {
LoadedFiles: [],

LoadFile: function (url) {
    var self = this;
    if (this.LoadedFiles.contains(url)) return;

    var xhr = new XMLHttpRequest();
    xhr.onload = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                self.LoadedFiles.push(url);
                self.AddScript(xhr.responseText);
            } else {
                if (console) console.error(xhr.statusText);
            }
        }
    };
    xhr.open("GET", url, false);/*last parameter defines if call is async or not*/
    xhr.send(null);
},

AddScript: function (code) {
    var oNew = document.createElement("script");
    oNew.type = "text/javascript";
    oNew.textContent = code;
    document.getElementsByTagName("head")[0].appendChild(oNew);
}
};

/*Load script file. ScriptLoader will check if you try to load a file that has already been loaded (this check might be better, but I'm lazy).*/

ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
/*this will be executed right after upper lines. It requires jquery to execute. It requires a HTML input with id "tb1"*/
$(function () { alert($('#tb1').val()); });

Die Technik, die wir bei der Arbeit verwenden, besteht darin, die Javascript-Datei mithilfe einer AJAX-Anfrage anzufordern und dann eval() zurückzugeben.Wenn Sie die Prototypenbibliothek verwenden, unterstützen sie diese Funktionalität in ihrem Ajax.Request-Aufruf.

jquery hat dieses Problem für mich mit seiner Funktion .append() gelöst- Habe dies verwendet, um das komplette JQuery-UI-Paket zu laden

/*
 * FILENAME : project.library.js
 * USAGE    : loads any javascript library
 */
    var dirPath = "../js/";
    var library = ["functions.js","swfobject.js","jquery.jeditable.mini.js","jquery-ui-1.8.8.custom.min.js","ui/jquery.ui.core.min.js","ui/jquery.ui.widget.min.js","ui/jquery.ui.position.min.js","ui/jquery.ui.button.min.js","ui/jquery.ui.mouse.min.js","ui/jquery.ui.dialog.min.js","ui/jquery.effects.core.min.js","ui/jquery.effects.blind.min.js","ui/jquery.effects.fade.min.js","ui/jquery.effects.slide.min.js","ui/jquery.effects.transfer.min.js"];

    for(var script in library){
        $('head').append('<script type="text/javascript" src="' + dirPath + library[script] + '"></script>');
    }

Benutzen - Im Kopf Ihres HTML/PHP/etc, nachdem Sie jquery.js importiert haben, fügen Sie einfach diese eine Datei ein, um sie in die gesamte Bibliothek zu laden und sie an den Kopf anzuhängen ...

<script type="text/javascript" src="project.library.js"></script>

Halten Sie es schön, kurz, einfach und wartbar!:]

// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
    FULL_PATH + 'plugins/script.js'      // Script example
    FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library 
    FULL_PATH + 'plugins/crypto-js/hmac-sha1.js',      // CryptoJS
    FULL_PATH + 'plugins/crypto-js/enc-base64-min.js'  // CryptoJS
];

function load(url)
{
    var ajax = new XMLHttpRequest();
    ajax.open('GET', url, false);
    ajax.onreadystatechange = function ()
    {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4)
        {
            switch(ajax.status)
            {
                case 200:
                    eval.apply( window, [script] );
                    console.log("library loaded: ", url);
                    break;
                default:
                    console.log("ERROR: library not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

 // initialize a single load 
load('plugins/script.js');

// initialize a full load of scripts
if (s.length > 0)
{
    for (i = 0; i < s.length; i++)
    {
        load(s[i]);
    }
}

Dieser Code ist einfach ein kurzes Funktionsbeispiel dafür könnte erfordern zusätzliche Funktionsfunktionen für vollständige Unterstützung auf jeder (oder gegebenen) Plattform.

Es gibt einen neuen vorgeschlagenen ECMA-Standard namens dynamischer Import, kürzlich in Chrome und Safari integriert.

const moduleSpecifier = './dir/someModule.js';

import(moduleSpecifier)
   .then(someModule => someModule.foo()); // executes foo method in someModule

Es gibt Skripte, die speziell für diesen Zweck entwickelt wurden.

yepnope.js ist in Modernizr integriert und lab.js ist eine optimiertere (aber weniger benutzerfreundliche) Version.

Ich würde nicht empfehlen, dies über eine große Bibliothek wie Jquery oder Prototype zu tun – denn einer der Hauptvorteile eines Skriptladeprogramms ist die Möglichkeit, Skripte frühzeitig zu laden – Sie sollten nicht warten müssen, bis JQuery und alle Ihre Dom-Elemente geladen sind Führen Sie eine Prüfung durch, um festzustellen, ob Sie ein Skript dynamisch laden möchten.

Ich habe ein einfaches Modul geschrieben, das das Importieren/Einbinden von Modulskripten in JavaScript automatisiert.Probieren Sie es aus und ersparen Sie sich bitte ein Feedback!:) Eine ausführliche Erklärung des Codes finden Sie in diesem Blogbeitrag: http://stamat.wordpress.com/2013/04/12/javascript-require-import-include-modules/

var _rmod = _rmod || {}; //require module namespace
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark the root directory of your library, any library


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };

    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

//you can rename based on your liking. I chose require, but it can be called include or anything else that is easy for you to remember or write, except import because it is reserved for future use.
var require = function(script_name) {
    var np = script_name.split('.');
    if (np[np.length-1] === '*') {
        np.pop();
        np.push('_all');
    }

    script_name = np.join('.');
    var uri = _rmod.libpath + np.join('/')+'.js';
    if (!_rmod.loading.scripts.hasOwnProperty(script_name) 
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri, 
            _rmod.requireCallback, 
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.push(fn);
};

// ----- USAGE -----

require('ivar.util.array');
require('ivar.util.string');
require('ivar.net.*');

ready(function(){
    //do something when required scripts are loaded
});

Ich bin in all diesen Beispielen verloren, aber heute musste ich eine externe .js von meiner Haupt-.js laden und habe Folgendes getan:

document.write("<script src='https://www.google.com/recaptcha/api.js'></script>");

Hier ist ein einfaches mit Rückruf und IE-Unterstützung:

function loadScript(url, callback) {

    var script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState) { //IE
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" || script.readyState == "complete") {
                script.onreadystatechange = null;
                callback();
            }
        };
    } else { //Others
        script.onload = function () {
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

loadScript("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {

     //jQuery loaded
     console.log('jquery loaded');

});

Hier ein einfaches Beispiel für eine Funktion zum Laden von JS-Dateien.Relevante Punkte:

  • Da Sie jQuery nicht benötigen, können Sie damit zunächst auch die Datei jQuery.js laden
  • Es ist asynchron mit dem Rückruf
  • Es stellt sicher, dass es nur einmal geladen wird, da es ein Gehäuse mit den Aufzeichnungen der geladenen URLs führt und so die Nutzung des Netzwerks vermeidet
  • im Gegensatz zu jQuery $.ajax oder $.getScript Sie können Nonces verwenden und so Probleme mit CSP lösen unsafe-inline.Nutzen Sie einfach die Immobilie script.nonce
var getScriptOnce = function() {

    var scriptArray = []; //array of urls (closure)

    //function to defer loading of script
    return function (url, callback){
        //the array doesn't have such url
        if (scriptArray.indexOf(url) === -1){

            var script=document.createElement('script');
            script.src=url;
            var head=document.getElementsByTagName('head')[0],
                done=false;

            script.onload=script.onreadystatechange = function(){
                if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
                    done=true;
                    if (typeof callback === 'function') {
                        callback();
                    }
                    script.onload = script.onreadystatechange = null;
                    head.removeChild(script);

                    scriptArray.push(url);
                }
            };

            head.appendChild(script);
        }
    };
}();

Jetzt verwenden Sie es einfach per

getScriptOnce("url_of_your_JS_file.js");

Ein absurder Einzeiler für diejenigen, die denken, dass das Laden einer js-Bibliothek nicht mehr als eine Codezeile erfordern sollte :P

await new Promise((resolve, reject) => {let js = document.createElement("script"); js.src="mylibrary.js"; js.onload=resolve; js.onerror=reject; document.body.appendChild(js)});

Wenn es sich bei dem Skript, das Sie importieren möchten, um ein Modul handelt, können Sie natürlich das verwenden import(...) Funktion.

Alle wichtigen Javascript-Bibliotheken wie JScript, Prototyp und YUI unterstützen das Laden von Skriptdateien.In YUI können Sie beispielsweise nach dem Laden des Kerns Folgendes tun, um das Kalendersteuerelement zu laden

var loader = new YAHOO.util.YUILoader({

    require: ['calendar'], // what components?

    base: '../../build/',//where do they live?

    //filter: "DEBUG",  //use debug versions (or apply some
                        //some other filter?

    //loadOptional: true, //load all optional dependencies?

    //onSuccess is the function that YUI Loader
    //should call when all components are successfully loaded.
    onSuccess: function() {
        //Once the YUI Calendar Control and dependencies are on
        //the page, we'll verify that our target container is 
        //available in the DOM and then instantiate a default
        //calendar into it:
        YAHOO.util.Event.onAvailable("calendar_container", function() {
            var myCal = new YAHOO.widget.Calendar("mycal_id", "calendar_container");
            myCal.render();
        })
     },

    // should a failure occur, the onFailure function will be executed
    onFailure: function(o) {
        alert("error: " + YAHOO.lang.dump(o));
    }

 });

// Calculate the dependency and insert the required scripts and css resources
// into the document
loader.insert();

Ich weiß, dass meine Antwort auf diese Frage etwas spät ist, aber hier ist ein toller Artikel in www.html5rocks.com - Tauchen Sie tief in die trüben Gewässer des Skriptladens ein .

In diesem Artikel kommt man zu dem Schluss, dass im Hinblick auf die Browserunterstützung der beste Weg, eine JavaScript-Datei dynamisch zu laden, ohne die Inhaltswiedergabe zu blockieren, der folgende ist:

Wenn man bedenkt, dass Sie vier Skripte benannt haben script1.js, script2.js, script3.js, script4.js dann kannst du es damit machen Anwenden von async = false:

[
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
].forEach(function(src) {
  var script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.head.appendChild(script);
});

Jetzt, Spec sagt:Zusammen herunterladen, der Reihe nach ausführen, sobald alles heruntergeladen ist.

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 werden.

Safari 5.0 sagt: Ich verstehe „async“, verstehe 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 einen Workaround mit „onreadystatechange“.

Alles andere sagt: Ich bin dein Freund, wir machen das nach Vorschrift.

Nun der vollständige Code mit IE < 10 Workaround:

var scripts = [
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
];
var src;
var script;
var pendingScripts = [];
var firstScript = document.scripts[0];

// Watch scripts load in IE
function stateChange() {
  // Execute as many scripts in order as we can
  var pendingScript;
  while (pendingScripts[0] && pendingScripts[0].readyState == 'loaded') {
    pendingScript = pendingScripts.shift();
    // avoid future loading events from this script (eg, if src changes)
    pendingScript.onreadystatechange = null;
    // can't just appendChild, old IE bug if element isn't closed
    firstScript.parentNode.insertBefore(pendingScript, firstScript);
  }
}

// loop through our script urls
while (src = scripts.shift()) {
  if ('async' in firstScript) { // modern browsers
    script = document.createElement('script');
    script.async = false;
    script.src = src;
    document.head.appendChild(script);
  }
  else if (firstScript.readyState) { // IE<10
    // create a script and add it to our todo pile
    script = document.createElement('script');
    pendingScripts.push(script);
    // listen for state changes
    script.onreadystatechange = stateChange;
    // must set src AFTER adding onreadystatechange listener
    // else we’ll miss the loaded event for cached scripts
    script.src = src;
  }
  else { // fall back to defer
    document.write('<script src="' + src + '" defer></'+'script>');
  }
}

Ein paar Tricks und Verkleinerung später sind es 362 Bytes

!function(e,t,r){function n(){for(;d[0]&&"loaded"==d[0][f];)c=d.shift(),c[o]=!i.parentNode.insertBefore(c,i)}for(var s,a,c,d=[],i=e.scripts[0],o="onreadystatechange",f="readyState";s=r.shift();)a=e.createElement(t),"async"in i?(a.async=!1,e.head.appendChild(a)):i[f]?(d.push(a),a[o]=n):e.write("<"+t+' src="'+s+'" defer></'+t+">"),a.src=s}(document,"script",[
  "//other-domain.com/1.js",
  "2.js"
])

Etwas wie das...

<script>
     $(document).ready(function() {
          $('body').append('<script src="https://maps.googleapis.com/maps/api/js?key=KEY&libraries=places&callback=getCurrentPickupLocation" async defer><\/script>');
     });
</script>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top