如果在头部注入多个包含本地和远程脚本文件的脚本标签,可能会出现这样的情况:依赖外部脚本(如从 googleapis 加载 jQuery)的本地脚本将出现错误,因为本地脚本可能在外部脚本加载之前被加载,导致类似这样的问题:(jquery.some-plugin.js 中出现“jQuery 未定义”的错误)。
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js";
head.appendChild(script);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = "/jquery.some-plugin.js";
head.appendChild(script);
当然,这种情况就是 .onload() 的作用所在,但如果要加载多个脚本,这可能会很麻烦。
为了解决这个问题,我编写了这个函数,它将保持一个要加载的脚本队列,在前一个脚本完成后加载每个后续项目,并返回一个 Promise,该 Promise 在脚本(或队列中的最后一个脚本,如果没有参数)加载完成时解析。
load_script = function(src) {
// Initialize scripts queue
if( load_script.scripts === undefined ) {
load_script.scripts = [];
load_script.index = -1;
load_script.loading = false;
load_script.next = function() {
if( load_script.loading ) return;
// Load the next queue item
load_script.loading = true;
var item = load_script.scripts[++load_script.index];
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = item.src;
// When complete, start next item in queue and resolve this item's promise
script.onload = () => {
load_script.loading = false;
if( load_script.index < load_script.scripts.length - 1 ) load_script.next();
item.resolve();
};
head.appendChild(script);
};
};
// Adding a script to the queue
if( src ) {
// Check if already added
for(var i=0; i < load_script.scripts.length; i++) {
if( load_script.scripts[i].src == src ) return load_script.scripts[i].promise;
}
// Add to the queue
var item = { src: src };
item.promise = new Promise(resolve => {item.resolve = resolve;});
load_script.scripts.push(item);
load_script.next();
}
// Return the promise of the last queue item
return load_script.scripts[ load_script.scripts.length - 1 ].promise;
};
通过添加脚本来确保在开始下一个脚本之前完成先前的脚本,可以像这样完成...
["https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js",
"/jquery.some-plugin.js",
"/dependant-on-plugin.js",
].forEach(load_script);
或者加载脚本并使用返回的Promise,在其完成时执行工作...
load_script("some-script.js")
.then(function() {
});
$.getScript()
吗? - Jai<script>//function<\script>
添加到文档的头部。 - john3825.readyState()
检查状态也无法解决。也许EventListner
可以解决问题,但是由于动态加载的趋势,所有这些方法都不太好,参考链接。 - john3825