javascript 一个接一个地加载一个脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15292020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Load one-script-after another
提问by Arno 2501
I have this simple function which loads scriptsinto the current DOM:
我有一个简单的函数,可以将脚本加载到当前的 DOM 中:
function loadscripts ( async ) {
if( async === undefined ) {
async = false;
}
var scripts = [];
var _scripts = ['jquery.min.js', 'bootstrap.min.js', 'plugins.js', 'main.js'];
for(var s in _scripts) {
scripts[s] = document.createElement('script');
scripts[s].type = 'text/javascript';
scripts[s].src = _scripts[s];
scripts[s].async = async;
document.getElementsByTagName('head').appendChild( scripts[s] );
}
}
They are loaded fine and without no errors. I know there are event handlers when loading scripts programmatically:
它们加载良好,没有错误。我知道以编程方式加载脚本时有事件处理程序:
- onreadystatechange, and
- onload, etc
- onreadystatechange,和
- 加载等
Now I would like to wish to do the following:
现在我想做以下事情:
- Load first script from the array, and when the event handlers are COMPLETE load the next one, and so on (recursively).
- 从数组加载第一个脚本,当事件处理程序完成时加载下一个,依此类推(递归)。
Sorry, I have not provided the onreadystatechange
and onload
events in my function.
抱歉,我没有在我的函数中提供onreadystatechange
和onload
事件。
回答by Arno 2501
I would do this that way :
我会这样做:
LoadScripts();
function LoadScripts(async)
{
if( async === undefined ) {
async = false;
}
var scripts = [];
var _scripts = ['jquery.min.js', 'bootstrap.min.js', 'plugins.js', 'main.js'];
if(async){
LoadScriptsAsync(_scripts, scripts)
}else{
LoadScriptsSync(_scripts,scripts)
}
}
// what you are looking for :
function LoadScriptsSync (_scripts, scripts) {
var x = 0;
var loopArray = function(_scripts, scripts) {
// call itself
loadScript(_scripts[x], scripts[x], function(){
// set x to next item
x++;
// any more items in array?
if(x < _scripts.length) {
loopArray(_scripts, scripts);
}
});
}
loopArray(_scripts, scripts);
}
// async load as in your code
function LoadScriptsAsync (_scripts, scripts){
for(var i = 0;i < _scripts.length;i++) {
loadScript(_scripts[i], scripts[i], function(){});
}
}
// load script function with callback to handle synchronicity
function loadScript( src, script, callback ){
script = document.createElement('script');
script.onerror = function() {
// handling error when loading script
alert('Error to handle')
}
script.onload = function(){
console.log(src + ' loaded ')
callback();
}
script.src = src;
document.getElementsByTagName('head')[0].appendChild(script);
}
回答by sroes
Try this:
试试这个:
function loadscripts ( async ) {
if( async === undefined ) {
async = false;
}
var scripts = [];
var _scripts = ['jquery.min.js', 'bootstrap.min.js', 'plugins.js', 'main.js'];
for(var s in _scripts) {
scripts[s] = document.createElement('script');
scripts[s].type = 'text/javascript';
scripts[s].src = _scripts[s];
scripts[s].async = async;
}
var loadNextScript = function() {
var script = scripts.shift();
var loaded = false;
document.getElementsByTagName('head').appendChild( script );
script.onload = script.onreadystatechange = function() {
var rs = this.readyState;
if (rs && rs != 'complete' && rs != 'loaded') return;
if (loaded) return;
loaded = true;
if (scripts.length) {
loadNextScript();
} else {
// done
}
};
};
loadNextScript();
}
回答by Matt
You could do it with promises like this.
你可以用这样的承诺来做到这一点。
// loads an individual script
var loadScript = function (path) {
// generate promise
return new Promise(function (fulfill, reject) {
// create object
var script = document.createElement('script');
// when it loads or the ready state changes
script.onload = script.onreadystatechange = function () {
// make sure it's finished, then fullfill the promise
if (!this.readyState || this.readyState == 'complete') fulfill(this);
};
// begin loading it
script.src = path;
// add to head
document.getElementsByTagName('head')[0].appendChild(script);
});
};
// this is the one you want
var loadScripts = function (scripts) {
return scripts.reduce(function (queue, path) {
// once the current item on the queue has loaded, load the next one
return queue.then(function () {
// individual script
return loadScript(path);
});
}, Promise.resolve() /* this bit is so queue is always a promise */);
};
Usage:
用法:
getScripts(["foo.js", "bar.js"]).then(function () {
// whatever you want to happen when it's all done
});
It doesn't do any error handling though, so you'll have to implement that it if you need it.
但是它不做任何错误处理,所以如果你需要它,你必须实现它。
回答by kris
Had to load scripts in given order x,y,z and since I only had a few of them. This approach worked for me. Could not load these in body or head since they are quite big and I'm using a static landing page.
必须按给定的顺序 x,y,z 加载脚本,因为我只有其中的几个。这种方法对我有用。无法在正文或头部加载这些内容,因为它们很大,而且我使用的是静态登录页面。
document.addEventListener('DOMContentLoaded', function(event) {
// initial DOM loaded
var vendorJS = document.createElement('script');
vendorJS.src = 'assets/vendor.js';
var appJS = document.createElement('script');
appJS.src = 'assets/application.js';
var envJS = document.createElement('script');
envJS.src = 'assets/env.js';
document.body.appendChild(vendorJS);
vendorJS.onload = vendorJS.onreadystatechange = function() {
document.body.appendChild(appJS);
appJS.onload = appJS.onreadystatechange = function() {
document.body.appendChild(envJS);
};
};
});
回答by Rohit Parte
We can load one script after another in html by using lab.min.js.
我们可以使用 lab.min.js 在 html 中加载一个又一个的脚本。
This library run in Synchronous way.
该库以同步方式运行。
<script>
var _DIR_ = "js/vendor/";
$LAB.setOptions({
AlwaysPreserveOrder: true
});
$LAB
.queueScript(_DIR_ + 'jquery-v2-1-3.min.js')
.queueWait()
.queueScript(_DIR_ + 'angular.min.js')
.queueWait()
.queueScript(_DIR_ + 'socket.io-1.3.5.js')
.queueScript(_DIR_ + 'angular-bootstrap/ui-bootstrap-tpls.min.js')
.queueScript(_DIR_ + 'Angular plugins/angular-ui-notification.min.js')
.runQueue();
</script>