Javascript 当所有脚本通过$.getScript完成加载时调用处理程序
假设我们通过Javascript 当所有脚本通过$.getScript完成加载时调用处理程序,javascript,jquery,ajax,Javascript,Jquery,Ajax,假设我们通过$加载一组脚本。getScript: $.getScript( 'js/script1.js' ); $.getScript( 'js/script2.js' ); $.getScript( 'js/script3.js' ); 现在,我想在所有这些脚本加载完毕后调用一个处理程序。我尝试为全局绑定一个处理程序。根据,如果不再处理Ajax请求,将触发ajaxStop全局事件 $( document ).ajaxStop( handler ); 但它不起作用(不调用处理程序) 现场演
$加载一组脚本。getScript
:
$.getScript( 'js/script1.js' );
$.getScript( 'js/script2.js' );
$.getScript( 'js/script3.js' );
现在,我想在所有这些脚本加载完毕后调用一个处理程序。我尝试为全局绑定一个处理程序。根据,如果不再处理Ajax请求,将触发ajaxStop
全局事件
$( document ).ajaxStop( handler );
但它不起作用(不调用处理程序)
现场演示:
我怎样才能做到这一点呢?我对这个问题做了进一步的探讨,实际上跨域脚本请求才是关键。正如我在评论中所发布的,该场景已经实现,它将
global
选项设置为false
。这使得jQuery不会触发全局ajax事件。(但不知道为什么要实施这一计划。)
这可以通过(通过表示ajaxStop已启动)确认:
- 跨域,无脚本:通过
- 跨域,脚本:失败
- 没有跨域,没有脚本:通过
- 无跨域,脚本:通过
global
选项为true:
jQuery.ajaxPrefilter( "script", function() {
s.global = true;
});
这也使得这个失败的场景被忽略了。不管怎么说,你都做错了:) 以下是可能发生的事情之一: 假设脚本被缓存,那么它们可能很快就会被加载。 因此,在第一次调用
$.getScript('js/script1.js')之后代码>脚本将可用,并调用$.ajaxStop(may!!!),最坏的情况会发生三次
为了间接地回答你的问题,我会提出一个不同的解决方案,避免这种竞争条件。
您可以在这里尝试:
更新:稍微重构了代码
var urls, loadedUrls, log;
urls = [
'https://raw.github.com/h5bp/html5-boilerplate/master/js/script.js',
'https://raw.github.com/h5bp/html5-boilerplate/master/js/plugins.js',
'https://raw.github.com/h5bp/html5-boilerplate/master/js/libs/modernizr-2.0.6.min.js'
];
loadedUrls = [];
log = $( '#log' )[0];
urls.forEach(function ( url ) {
$.getScript( url, function () {
loadedUrls.push( url );
$( log ).append( 'loaded ' + url + '<br>' );
if( loadedUrls.length === urls.length ){
$( log ).append( '<b>all done!</b>' );
}
});
});
var-url、loadedUrls、log;
URL=[
'https://raw.github.com/h5bp/html5-boilerplate/master/js/script.js',
'https://raw.github.com/h5bp/html5-boilerplate/master/js/plugins.js',
'https://raw.github.com/h5bp/html5-boilerplate/master/js/libs/modernizr-2.0.6.min.js'
];
loadedUrls=[];
log=$('#log')[0];
forEach(函数(url){
$.getScript(url,函数(){
loadedUrls.push(url);
$(log).append('loaded'+url+'
');
if(loadedUrls.length==url.length){
$(log.append('all done!');
}
});
});
现场演示:在处理我自己的问题时,我找到了一个更好、更优雅的解决方案,它使用了。我想你已经知道这个函数了,也许是另一个用例,但是它对于加载文件和在所有事情完成后启动函数都非常有用。代码如下:
function getLatestNews() {
return $.get('/echo/js/?delay=2&js=', function(data) {
console.log('news data received');
$('.news').css({'color':'blue'});
});
}
function getLatestReactions() {
return $.get('/echo/js/?delay=5&js=', function(data) {
console.log('reactions data received');
$('.reactions').css({'color':'green'});
});
}
function prepareInterface() {
return $.Deferred(function(dfd) {
var latest = $('.news, .reactions');
latest.slideDown(500, dfd.resolve);
latest.addClass('active');
}).promise();
}
$.when(
getLatestNews(),
getLatestReactions(),
prepareInterface()
).then(function() {
console.log('fire after requests succeed');
$('.finished').html('I am done!');
}).fail(function() {
console.log('something went wrong!');
});
我做了一把小小提琴,你可以在那里查看代码
您可以在那里查看一个正在运行的副本,我从本教程中获取了这个片段,值得阅读整个教程,其中有很多关于异步ajax的好信息
您是否尝试过将承诺与$结合起来。when()
?(或者说,不管人们怎么做…@Pointy不,我还没有学会如何在jQuery中使用延迟。现在,我想知道为什么.ajaxStop()
失败了——我一定是用错了什么东西了……我不知道;我从未尝试过使用它。我来看看能不能在你的提琴上实现诺言。(一件稍微奇怪的事情是,“ajaxStop”事件的触发方式与jQuery源代码中的其他事件不同。)它在1.2.6中工作。@john_doe:可能是因为带有跨域脚本的ajaxPrefilter
(此处的场景)-请参阅。感谢您对此:)
@kritzikratzi是的,拥有第二个阵列是一个很好的解决方案。你不需要$.map
但是-在URL
数组上调用forEach
就足够了。@ŠimeVidas这是正确的,我写了很多mathematica代码,其中map和forEach基本相同…@kritzikratzi好吧,每个/forEach
都是一般的迭代器机制,然而,map
专门用于替换数组的值。是的,$.when().then()
模式很酷:)
我已经用这个模式解决了问题(请参阅我对上面问题的最后一条评论)。哦,我没有看到,它是隐藏的。啊,我喜欢这个模式!很好的解决方案。
var urls, loadedUrls, log;
urls = [
'https://raw.github.com/h5bp/html5-boilerplate/master/js/script.js',
'https://raw.github.com/h5bp/html5-boilerplate/master/js/plugins.js',
'https://raw.github.com/h5bp/html5-boilerplate/master/js/libs/modernizr-2.0.6.min.js'
];
loadedUrls = [];
log = $( '#log' )[0];
urls.forEach(function ( url ) {
$.getScript( url, function () {
loadedUrls.push( url );
$( log ).append( 'loaded ' + url + '<br>' );
if( loadedUrls.length === urls.length ){
$( log ).append( '<b>all done!</b>' );
}
});
});
function getLatestNews() {
return $.get('/echo/js/?delay=2&js=', function(data) {
console.log('news data received');
$('.news').css({'color':'blue'});
});
}
function getLatestReactions() {
return $.get('/echo/js/?delay=5&js=', function(data) {
console.log('reactions data received');
$('.reactions').css({'color':'green'});
});
}
function prepareInterface() {
return $.Deferred(function(dfd) {
var latest = $('.news, .reactions');
latest.slideDown(500, dfd.resolve);
latest.addClass('active');
}).promise();
}
$.when(
getLatestNews(),
getLatestReactions(),
prepareInterface()
).then(function() {
console.log('fire after requests succeed');
$('.finished').html('I am done!');
}).fail(function() {
console.log('something went wrong!');
});