Javascript 如何使用jQuery$.getScript()方法包含多个js文件
我正在尝试将javascript文件动态地包含到我的js文件中。我对此做了一些研究,发现jQuery$.getScript()方法是一种理想的方法Javascript 如何使用jQuery$.getScript()方法包含多个js文件,javascript,jquery,html,promise,Javascript,Jquery,Html,Promise,我正在尝试将javascript文件动态地包含到我的js文件中。我对此做了一些研究,发现jQuery$.getScript()方法是一种理想的方法 // jQuery $.getScript('/path/to/imported/script.js', function() { // script is now loaded and executed. // put your dependent JS here. // what if the JS code is dep
// jQuery
$.getScript('/path/to/imported/script.js', function()
{
// script is now loaded and executed.
// put your dependent JS here.
// what if the JS code is dependent on multiple JS files?
});
但是我想知道这个方法是否可以一次加载多个脚本?我之所以问这个问题,是因为有时候我的javascript文件依赖于多个js文件
先谢谢你 使用或(包括yepnope.js作为modernizer.load
)
更新
function getScripts( scripts, onScript, onComplete )
{
this.async = true;
this.cache = false;
this.data = null;
this.complete = function () { $.scriptHandler.loaded(); };
this.scripts = scripts;
this.onScript = onScript;
this.onComplete = onComplete;
this.total = scripts.length;
this.progress = 0;
};
getScripts.prototype.fetch = function() {
$.scriptHandler = this;
var src = this.scripts[ this.progress ];
console.log('%cFetching %s','color:#ffbc2e;', src);
$.ajax({
crossDomain:true,
async:this.async,
cache:this.cache,
type:'GET',
url: src,
data:this.data,
statusCode: {
200: this.complete
},
dataType:'script'
});
};
getScripts.prototype.loaded = function () {
this.progress++;
if( this.progress >= this.total ) {
if(this.onComplete) this.onComplete();
} else {
this.fetch();
};
if(this.onScript) this.onScript();
};
接下来,这里有一个与您目前使用的yepnope相当的示例,显示了对多个脚本的依赖关系:
yepnope({
load: ['script1.js', 'script2.js', 'script3.js'],
complete: function () {
// all the scripts have loaded, do whatever you want here
}
});
你要找的是一个AMD兼容的加载器(比如require.js) 如果你查一下,有很多好的开源软件。基本上,这允许您定义一个代码模块,如果它依赖于其他代码模块,它将等待这些模块完成下载后再继续运行。通过这种方式,您可以异步加载10个模块,即使其中一个模块依赖于其他几个模块运行,也应该没有问题。答案是 您可以将承诺与
getScript()
一起使用,并等待所有脚本加载完毕,例如:
$.when(
$.getScript( "/mypath/myscript1.js" ),
$.getScript( "/mypath/myscript2.js" ),
$.getScript( "/mypath/myscript3.js" ),
$.Deferred(function( deferred ){
$( deferred.resolve );
})
).done(function(){
//place your code here, the scripts are all loaded
});
在上面的代码中,在$()
中添加一个延迟函数并解析它就像在jQuery调用中放置任何其他函数一样,就像$(func)
,这与
$(function() { func(); });
i、 e.它等待DOM准备就绪,因此在上面的示例中,$。当
等待加载所有脚本时,和等待DOM准备就绪,因为$。延迟的调用在DOM准备就绪回调中解析
对于更通用的用途,一个方便的函数 可以按如下方式创建接受任何脚本数组的实用程序函数:
$.getMultiScripts = function(arr, path) {
var _arr = $.map(arr, function(scr) {
return $.getScript( (path||"") + scr );
});
_arr.push($.Deferred(function( deferred ){
$( deferred.resolve );
}));
return $.when.apply($, _arr);
}
可以这样使用
var script_arr = [
'myscript1.js',
'myscript2.js',
'myscript3.js'
];
$.getMultiScripts(script_arr, '/mypath/').done(function() {
// all scripts loaded
});
其中,路径将作为所有脚本的前缀,并且也是可选的,这意味着如果数组包含完整URL,那么其中一个也可以这样做,并将路径一起省略
$.getMultiScripts(script_arr).done(function() { ...
论点、错误等。 另请注意,
done
回调将包含许多与传入脚本匹配的参数,每个参数表示一个包含响应的数组
$.getMultiScripts(script_arr).done(function(response1, response2, response3) { ...
其中每个数组将包含类似于[加载的文件的内容、状态、xhr\u对象]
的内容。
我们通常不需要访问这些参数,因为脚本将自动加载,而且大多数情况下,done
回调是我们真正想要知道所有脚本都已加载的全部,我只是为了完整性而添加它,对于少数需要访问加载文件中的实际文本的情况,或者需要访问每个XHR对象或类似对象时
此外,如果任何脚本加载失败,将调用失败处理程序,并且不会加载后续脚本
$.getMultiScripts(script_arr).done(function() {
// all done
}).fail(function(error) {
// one or more scripts failed to load
}).always(function() {
// always called, both on success and error
});
在前一个脚本的回调中加载以下所需脚本,如下所示:
$.getScript('scripta.js', function()
{
$.getScript('scriptb.js', function()
{
// run script that depends on scripta.js and scriptb.js
});
});
我在多脚本加载方面遇到了很多问题,其中一个问题是(至少在Chrome中)在通过Ajax成功加载后,同一个域热加载的脚本没有实际运行,而跨域加载的效果非常好!:( 原始问题的选定答案不可靠 经过多次迭代之后,这里是我对getScript的最终答案,我将按照特定的严格顺序异步加载多个脚本,使用每个脚本加载的回调选项和完成时的整体回调,并在jQuery 2.1+和Chrome、Firefox以及被抛弃的Internet Explorer的现代版本中进行测试 我的测试用例是为THREE.JS webGL渲染加载文件,然后在三个全局文件可用时启动渲染脚本,使用传递给onComplete的匿名函数调用的间隔检查 原型函数(getScripts)
function getScripts( scripts, onScript, onComplete )
{
this.async = true;
this.cache = false;
this.data = null;
this.complete = function () { $.scriptHandler.loaded(); };
this.scripts = scripts;
this.onScript = onScript;
this.onComplete = onComplete;
this.total = scripts.length;
this.progress = 0;
};
getScripts.prototype.fetch = function() {
$.scriptHandler = this;
var src = this.scripts[ this.progress ];
console.log('%cFetching %s','color:#ffbc2e;', src);
$.ajax({
crossDomain:true,
async:this.async,
cache:this.cache,
type:'GET',
url: src,
data:this.data,
statusCode: {
200: this.complete
},
dataType:'script'
});
};
getScripts.prototype.loaded = function () {
this.progress++;
if( this.progress >= this.total ) {
if(this.onComplete) this.onComplete();
} else {
this.fetch();
};
if(this.onScript) this.onScript();
};
如何使用
function getScripts( scripts, onScript, onComplete )
{
this.async = true;
this.cache = false;
this.data = null;
this.complete = function () { $.scriptHandler.loaded(); };
this.scripts = scripts;
this.onScript = onScript;
this.onComplete = onComplete;
this.total = scripts.length;
this.progress = 0;
};
getScripts.prototype.fetch = function() {
$.scriptHandler = this;
var src = this.scripts[ this.progress ];
console.log('%cFetching %s','color:#ffbc2e;', src);
$.ajax({
crossDomain:true,
async:this.async,
cache:this.cache,
type:'GET',
url: src,
data:this.data,
statusCode: {
200: this.complete
},
dataType:'script'
});
};
getScripts.prototype.loaded = function () {
this.progress++;
if( this.progress >= this.total ) {
if(this.onComplete) this.onComplete();
} else {
this.fetch();
};
if(this.onScript) this.onScript();
};
var scripts = new getScripts(
['script1.js','script2.js','script.js'],
function() {
/* Optional - Executed each time a script has loaded (Use for Progress updates?) */
},
function () {
/* Optional - Executed when the entire list of scripts has been loaded */
}
);
scripts.fetch();
该函数与我发现的使用延迟(现在不推荐?)的函数一样,在我的试用中,何时、成功和完成不是100%可靠的!?,因此该函数和statusCode的使用就是一个例子
如果愿意,您可能需要添加错误/失败处理行为。以上Andrew Marc Newton综合答案的较短版本。此答案不检查状态代码是否成功,您应该这样做以避免未定义的UI行为 这是一个恼人的系统,我可以保证jQuery,但没有其他包含,所以我想要一个足够短的技术,如果强制进入外部脚本,就不会被转移到外部脚本中(通过将索引0传递到第一个“递归”调用,可以使它更短,但风格习惯的力量让我添加了糖) 我还将依赖项列表分配给一个模块名,因此该块可以包含在需要“module1”的任何地方,脚本和依赖项初始化只包含/运行一次(您可以在回调中记录
索引
,并查看一组有序的AJAX请求运行)
有一个插件扩展了jQuery的getScript方法。允许异步和同步加载,并使用jQuery的缓存机制。完全公开,我写了这篇文章。如果你找到更好的方法,请随意贡献
我实现了一个简单的函数来并行加载多个脚本: 作用 用法
您可以使用
$。当使用-方法时,请尝试以下函数:
function loadScripts(scripts) {
scripts.forEach(function (item, i) {
item = $.getScript(item);
});
return $.when.apply($, scripts);
}
此函数的使用方式如下:
loadScripts(['path/to/script-a.js', 'path/to/script-b.js']).done(function (respA, respB) {
// both scripts are loaded; do something funny
});
这是使用承诺的方法,开销最小。逐个加载n个脚本(例如,如果第二个文件需要第一个脚本,则很有用):
此函数将确保在完全加载依赖项文件后加载文件。您只需按顺序提供文件,并记住对其他文件的依赖项
function loadFiles(files, fn) {
if (!files.length) {
files = [];
}
var head = document.head || document.getElementsByTagName('head')[0];
function loadFile(index) {
if (files.length > index) {
var fileref = document.createElement('script');
fileref.setAttribute("type", "text/javascript");
fileref.setAttribute("src", files[index]);
head.appendChild(fileref);
index = index + 1;
// Used to call a callback function
fileref.onload = function () {
loadFile(index);
}
} else if(fn){
fn();
}
}
loadFile(0);
}
回答得很好,阿德内奥
我
(function self(a,cb,i){
i = i || 0;
cb = cb || function(){};
if(i==a.length)return cb();
$.getScript(a[i++],self.bind(0,a,cb,i));
})(['list','of','script','urls'],function(){console.log('done')});
function loadFiles(files, fn) {
if (!files.length) {
files = [];
}
var head = document.head || document.getElementsByTagName('head')[0];
function loadFile(index) {
if (files.length > index) {
var fileref = document.createElement('script');
fileref.setAttribute("type", "text/javascript");
fileref.setAttribute("src", files[index]);
head.appendChild(fileref);
index = index + 1;
// Used to call a callback function
fileref.onload = function () {
loadFile(index);
}
} else if(fn){
fn();
}
}
loadFile(0);
}
function loadMultipleScripts(scripts, callback){
var array = [];
scripts.forEach(function(script){
array.push($.getScript( script ))
});
array.push($.Deferred(function( deferred ){
$( deferred.resolve );
}));
$.when.apply($, array).done(function(){
if (callback){
callback();
}
});
}
// Usage
//$.getMultiResources(['script-1.js','style-1.css'], 'assets/somePath/')
// .done(function () {})
// .fail(function (error) {})
// .always(function () {});
(function ($) {
$.getMultiResources = function (arr, pathOptional, cache) {
cache = (typeof cache === 'undefined') ? true : cache;
var _arr = $.map(arr, function (src) {
var srcpath = (pathOptional || '') + src;
if (/.css$/i.test(srcpath)) {
return $.ajax({
type: 'GET',
url: srcpath,
dataType: 'text',
cache: cache,
success: function () {
$('<link>', {
rel: 'stylesheet',
type: 'text/css',
'href': srcpath
}).appendTo('head');
}
});
} else {
return $.ajax({
type: 'GET',
url: srcpath,
dataType: 'script',
cache: cache
});
}
});
//
_arr.push($.Deferred(function (deferred) {
$(deferred.resolve);
}));
//
return $.when.apply($, _arr);
};
})(jQuery);
function getScripts(scripts) {
var prArr = [];
scripts.forEach(function(script) {
(function(script){
prArr .push(new Promise(function(resolve){
$.getScript(script, function () {
resolve();
});
}));
})(script);
});
return Promise.all(prArr, function(){
return true;
});
}
var jsarr = ['script1.js','script2.js'];
getScripts(jsarr).then(function(){
...
});
var scriptsToLoad = [
"script1.js",
"script2.js",
"script3.js",
];
scriptsToLoad.forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.body.appendChild(script);
});
function loadScripts(urls, path) {
return new Promise(function(resolve) {
urls.forEach(function(src, i) {
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = (path || "") + src;
script.async = false;
// If last script, bind the callback event to resolve
if(i == urls.length-1) {
// Multiple binding for browser compatibility
script.onreadystatechange = resolve;
script.onload = resolve;
}
// Fire the loading
document.body.appendChild(script);
});
});
}
let JSDependencies = ["jquery.js",
"LibraryNeedingJquery.js",
"ParametersNeedingLibrary.js"];
loadScripts(JSDependencies,'JavaScript/').then(taskNeedingParameters);
var queue = ['url/links/go/here'];
ProcessScripts(function() { // All done do what ever you want
}, 0);
function ProcessScripts(cb, index) {
getScript(queue[index], function() {
index++;
if (index === queue.length) { // Reached the end
cb();
} else {
return ProcessScripts(cb, index);
}
});
}
function getScript(script, callback) {
$.getScript(script, function() {
callback();
});
}
$.getMultiScripts = function(arr, path) {
function executeInOrder(scr, code, resolve) {
// if its the first script that should be executed
if (scr == arr[0]) {
arr.shift();
eval(code);
resolve();
console.log('executed', scr);
} else {
// waiting
setTimeout(function(){
executeInOrder(scr, code, resolve);
}, 50);
}
}
var _arr = $.map(arr, function(scr) {
return new Promise((resolve) => {
jQuery.ajax({
type: "GET",
url: (path || '') + scr,
dataType: "text",
success: function(code) {
console.log('loaded ', scr);
executeInOrder(scr, code, resolve);
},
cache: true
});
});
});
_arr.push($.Deferred(function( deferred ){
$( deferred.resolve );
}));
return $.when.apply($, _arr);
}
var script_arr = [
'myscript1.js',
'myscript2.js',
'myscript3.js'
];
$.getMultiScripts(script_arr, '/mypath/').done(function() {
// all scripts loaded
});