动态加载多个JS文件并在所有准备就绪时触发回调

时间:2016-04-14 17:32:04

标签: javascript

我有几个需要使用JavaScript动态附加到DOM的JS和CSS文件。描述的方法here适用于1个文件。但是我有几个它们应该按照一定的顺序添加/加载:

var resources = {
  "jquery" : "jquery.js",
  "jqueryui" : "jquery_ui.js",
  "customScript" : "script.js"
}

如果重要 - 资源可以在数组中而不是在对象中。

我认为应该做的是在前一个资源的回调中加载每个下一个资源。并且最后一个资源的回调应该调用另一个函数,在我的例子中,它将呈现HTML。但是我不知道如何使用上面链接中给出的代码来组织它。另一个重要方面是应该使用纯JavaScript来完成。

任何线索?

谢谢!

3 个答案:

答案 0 :(得分:4)

如果你关心它们的加载顺序,我建议你创建一个资源数组而不是一个对象。我希望这个解决方案能解决你的问题。

var urls = ['https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.js',
  'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.slim.js'
];

var i = 0;

var recursiveCallback = function() {
  if (++i < urls.length) {
    loadScript(urls[i], recursiveCallback)
  } else {
    alert('Loading Success !');
  }
}

loadScript(urls[0], recursiveCallback);

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);
}

工作小提琴:https://jsfiddle.net/nikdtu/6uj0t0hp/

答案 1 :(得分:-1)

我没有测试,但在概念上这应该工作。循环穿过你的对象。每次循环创建脚本元素,然后将脚本添加到刚刚创建的脚本元素的源。获取资源的最后一个脚本(lastObj)并将其与resource[key]进行比较,如果它们等效,则调用onload函数,这将确定何时加载最后一个脚本。

var resources = {
  "jquery": "jquery.js",
  "jqueryui": "jquery_ui.js",
  "customScript": "script.js"
}

var lastObj = resources[Object.keys(resources)[Object.keys(resources).length - 1]]

var script = [];
index = 0;
for (var key in resources) {
  script[index] = document.createElement('script');
  if (lastObj === resources[key]) {
    script[index].onload = function() {
      alert("last script loaded and ready");
    };
  }
  script[index].src = resources[key];
  document.getElementsByTagName('head')[0].appendChild(script[index]);
  index++;
}

答案 2 :(得分:-1)

如果您不关心旧浏览器,可以使用以下修改来加载它们。

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Stack Overflow</title>
    <link rel="stylesheet" type="text/css" href="css/jquery-ui.min.css">
    <script type="text/javascript" src="scripts/loader.js" ></script>
</head>
<body>
    <h1>Test javascript loading strategy</h1>
    <p id="result">Loading...</p>
    <p>Date: <input type="text" id="datepicker"></p>

</body>
</html>

loader.js

function loadScript(url){

    return new Promise(function(resolve, reject) {

        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;
                    resolve();
                }
            };
        } else {  //Others
            script.onload = function(){
                resolve();
            };
        }

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

    });
}

var resources = [
  "scripts/jquery.js",
  "scripts/jquery_ui.js",
  "scripts/script.js"
]

function loadAllResources() {
   return resources.reduce(function(prev, current) {

    return prev.then(function() {
      return loadScript(current);
    });

  }, Promise.resolve());
}

loadAllResources().then(function() {
  $('#result').text('Everything loaded');
});

自定义脚本script.js

$( "#datepicker" ).datepicker();

工作JSFiddle