best way of dynamic script loading

2019-02-10 06:20发布

问题:

I need to load some js files dynamically and sequentially(i.e. second script loads after load complete of first one, third after second and so on).

Question: how to detect when a script have been loaded? I have encountered problems with onload event - it not fires in IE8. After reading this, I tried to subscribe to onreadystatechange and wrote very ugly code for loading a script:

function loadScript(url, callback) {
        var isLoaded = false;
        var script = document.createElement('script');

        script.onreadystatechange = function () {
            if ((script.readyState == 'complete' || script.readyState == 'loaded') && !isLoaded) {
                if (callback) callback();
            }
        };
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', url);
        document.head.appendChild(script);
    };

Can you suggest better cross browser solution without such tricks?

UPD: Thanks for answers. What should I do if I need also to load jquery.js(for example, client have old version) :)?

回答1:

I think what you need is jQuery.getScript

The function takes a URL and a success method with which you can chain loading of scripts and therefore load them sequentially:

jQuery.getScript( url, function() { 
  jQuery.getScript( url2, function() 
    {/*... all 2 scripts finished loading */}
  );
});


回答2:

Here is my snippet for loading several scripts using jQuery.getScript();

function getScripts(inserts, callback)
{
    var nextInsert = inserts.shift();
    if (nextInsert != undefined)
    {
        console.log("calling"+nextInsert);
    jQuery.getScript(nextInsert, function(){ getScripts(inserts, callback); })
            .fail(function(jqxhr, settings, exception){alert("including "+nextInsert+" failed:\n" +exception)});
    }
    else
    {
        if (callback != undefined) callback();
    }
};

Usage:

var includes = [
    "js/script1.js",
    "js/script2.js",
    "js/script3.js"
];

getScripts(includes, function(){ /* typically a call to your init method comes here */; });


回答3:

RequireJS:

... is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.

Says it is IE 6+, Firefox2 2+, Safari 3.2+, Chrome 3+ and Opera 10+ compatible.



回答4:

In Chrome, we can use onload and onerror to replace onreadystatechange.