468 Stimmen

Dynamisches Laden von JS innerhalb von JS

Ich habe eine dynamische Webseite, wo ich eine externe JS-Datei importieren müssen (unter einer IF Bedingung) innerhalb einer anderen Javascript-Datei.

Ich habe versucht, nach einer praktikablen Lösung zu suchen, aber es hat nicht funktioniert.

Ich habe versucht, das Laden einer JS-Datei in das DOM mit document.createElement() aber es hat auch nicht funktioniert. Offenbar wurde die Js in das DOM geladen, aber war nicht in der aktuellen JS-Datei zugänglich.

Lösung in jQuery wird auch in Ordnung sein

923voto

Zirak Punkte 37644

Meine Vermutung ist, dass in Ihrer DOM-only-Lösung Sie etwas wie getan haben:

var script = document.createElement('script');
script.src = something;
//do stuff with the script

Zunächst einmal wird das nicht funktionieren, weil das Skript nicht in die Dokumentstruktur eingefügt wird, so dass es nicht geladen wird. Außerdem wird die Ausführung von Javascript fortgesetzt, während das andere Skript geladen wird, so dass dessen Inhalt erst dann zur Verfügung steht, wenn das Skript vollständig geladen ist.

Sie können sich das Skript anhören load Ereignis und machen Sie mit den Ergebnissen, was Sie wollen. So:

var script = document.createElement('script');
script.onload = function () {
    //do stuff with the script
};
script.src = something;

document.head.appendChild(script); //or something of the likes

179voto

kayen Punkte 4788

JQuery's $.getScript() ist manchmal fehlerhaft, deshalb verwende ich meine eigene Implementierung davon, wie:

jQuery.loadScript = function (url, callback) {
    jQuery.ajax({
        url: url,
        dataType: 'script',
        success: callback,
        async: true
    });
}

und verwenden Sie es wie:

if (typeof someObject == 'undefined') $.loadScript('url_to_someScript.js', function(){
    //Stuff to do after someScript has loaded
});

129voto

Anonymous JS Fan Punkte 1281

Da ich dies häufig tun muss, verwende ich dies:

var loadJS = function(url, implementationCode, location){
    //url is URL of external file, implementationCode is the code
    //to be called from the file, location is the location to 
    //insert the <script> element

    var scriptTag = document.createElement('script');
    scriptTag.src = url;

    scriptTag.onload = implementationCode;
    scriptTag.onreadystatechange = implementationCode;

    location.appendChild(scriptTag);
};
var yourCodeToBeCalled = function(){
//your code goes here
}
loadJS('yourcode.js', yourCodeToBeCalled, document.body);

Weitere Informationen finden Sie auf dieser Website Wie kann ich eine JavaScript-Datei in eine andere JavaScript-Datei einbinden? Das ist die Quelle meiner Funktionsidee.

30voto

muthu Punkte 5237

Sie können die js innerhalb der Seite dynamisch laden, nicht eine andere js-Datei.

Sie müssen die getScript um die js-Datei zu laden.

$.getScript("ajax/test.js", function(data, textStatus, jqxhr) {
  console.log(data); // data returned
  console.log(textStatus); // success
  console.log(jqxhr.status); // 200
  console.log('Load was performed.');
});

20voto

Stefan Steiger Punkte 72861

Nekromantie.

Ich verwende dies, um abhängige Skripte zu laden;
es funktioniert mit IE8+, ohne eine Abhängigkeit von einer anderen Bibliothek wie jQuery hinzuzufügen!

var cScriptLoader = (function ()
{
    function cScriptLoader(files)
    {
        var _this = this;
        this.log = function (t)
        {
            console.log("ScriptLoader: " + t);
        };
        this.withNoCache = function (filename)
        {
            if (filename.indexOf("?") === -1)
                filename += "?no_cache=" + new Date().getTime();
            else
                filename += "&no_cache=" + new Date().getTime();
            return filename;
        };
        this.loadStyle = function (filename)
        {
            // HTMLLinkElement
            var link = document.createElement("link");
            link.rel = "stylesheet";
            link.type = "text/css";
            link.href = _this.withNoCache(filename);
            _this.log('Loading style ' + filename);
            link.onload = function ()
            {
                _this.log('Loaded style "' + filename + '".');
            };
            link.onerror = function ()
            {
                _this.log('Error loading style "' + filename + '".');
            };
            _this.m_head.appendChild(link);
        };
        this.loadScript = function (i)
        {
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = _this.withNoCache(_this.m_js_files[i]);
            var loadNextScript = function ()
            {
                if (i + 1 < _this.m_js_files.length)
                {
                    _this.loadScript(i + 1);
                }
            };
            script.onload = function ()
            {
                _this.log('Loaded script "' + _this.m_js_files[i] + '".');
                loadNextScript();
            };
            script.onerror = function ()
            {
                _this.log('Error loading script "' + _this.m_js_files[i] + '".');
                loadNextScript();
            };
            _this.log('Loading script "' + _this.m_js_files[i] + '".');
            _this.m_head.appendChild(script);
        };
        this.loadFiles = function ()
        {
            // this.log(this.m_css_files);
            // this.log(this.m_js_files);
            for (var i = 0; i < _this.m_css_files.length; ++i)
                _this.loadStyle(_this.m_css_files[i]);
            _this.loadScript(0);
        };
        this.m_js_files = [];
        this.m_css_files = [];
        this.m_head = document.getElementsByTagName("head")[0];
        // this.m_head = document.head; // IE9+ only
        function endsWith(str, suffix)
        {
            if (str === null || suffix === null)
                return false;
            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }
        for (var i = 0; i < files.length; ++i)
        {
            if (endsWith(files[i], ".css"))
            {
                this.m_css_files.push(files[i]);
            }
            else if (endsWith(files[i], ".js"))
            {
                this.m_js_files.push(files[i]);
            }
            else
                this.log('Error unknown filetype "' + files[i] + '".');
        }
    }
    return cScriptLoader;
})();
var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();

Wenn Sie sich für die . -Version, mit der diese erstellt wurde:

class cScriptLoader {
    private m_js_files: string[];
    private m_css_files: string[];
    private m_head:HTMLHeadElement;

    private log = (t:any) =>
    {
        console.log("ScriptLoader: " + t);
    }

    constructor(files: string[]) {
        this.m_js_files = [];
        this.m_css_files = [];
        this.m_head = document.getElementsByTagName("head")[0];
        // this.m_head = document.head; // IE9+ only

        function endsWith(str:string, suffix:string):boolean 
        {
            if(str === null || suffix === null)
                return false;

            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }

        for(let i:number = 0; i < files.length; ++i) 
        {
            if(endsWith(files[i], ".css"))
            {
                this.m_css_files.push(files[i]);
            }
            else if(endsWith(files[i], ".js"))
            {
                this.m_js_files.push(files[i]);
            }
            else
                this.log('Error unknown filetype "' + files[i] +'".');
        }

    }

    public withNoCache = (filename:string):string =>
    {
        if(filename.indexOf("?") === -1)
            filename += "?no_cache=" + new Date().getTime();
        else
            filename += "&no_cache=" + new Date().getTime();

        return filename;    
    }

    public loadStyle = (filename:string) =>
    {
        // HTMLLinkElement
        let link = document.createElement("link");
        link.rel = "stylesheet";
        link.type = "text/css";
        link.href = this.withNoCache(filename);

        this.log('Loading style ' + filename);
        link.onload = () =>
        {
            this.log('Loaded style "' + filename + '".');

        };

        link.onerror = () =>
        {
            this.log('Error loading style "' + filename + '".');
        };

        this.m_head.appendChild(link);
    }

    public loadScript = (i:number) => 
    {
        let script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = this.withNoCache(this.m_js_files[i]);

        var loadNextScript = () => 
        {
            if (i + 1 < this.m_js_files.length)
            {
                this.loadScript(i + 1);
            }
        }

        script.onload = () =>
        {
            this.log('Loaded script "' + this.m_js_files[i] + '".');
            loadNextScript();
        };

        script.onerror = () =>
        {
            this.log('Error loading script "' + this.m_js_files[i] + '".');
            loadNextScript();
        };

        this.log('Loading script "' + this.m_js_files[i] + '".');
        this.m_head.appendChild(script);
    }

    public loadFiles = () => 
    {
        // this.log(this.m_css_files);
        // this.log(this.m_js_files);

        for(let i:number = 0; i < this.m_css_files.length; ++i)
            this.loadStyle(this.m_css_files[i])

        this.loadScript(0);
    }

}

var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();

Wenn Sie eine dynamische Liste von Skripten laden wollen, schreiben Sie die Skripte in ein Attribut wie data-main, z. B. <script src="scriptloader.js" data-main="file1.js,file2.js,file3.js,etc." ></script>
und machen eine element.getAttribute("data-main").split(',')

wie zum Beispiel

var target = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  // Note: this is for IE as IE doesn't support currentScript
  // this does not work if you have deferred loading with async
  // e.g. <script src="..." async="async" ></script>
  // https://web.archive.org/web/20180618155601/https://www.w3schools.com/TAgs/att_script_async.asp
  return scripts[scripts.length - 1];
})();

target.getAttribute("data-main").split(',')

um die Liste zu erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X