【问题标题】:Is it possible to pass a single parameter to $.when which contains two deferred objects?是否可以将单个参数传递给 $.when 包含两个延迟对象?
【发布时间】:2011-06-22 11:50:01
【问题描述】:

我只想在 jQuery 对象中的所有图像都已加载时执行一些代码。我可以这样做:

var img1Load = $.Deferred();
$('#img1').load(img1Load.resolve);

var img2Load = $.Deferred();
$('#img2').load(img2Load.resolve);

$.when(img1Load, img2Load).done(function(){
    console.log('both imgs loaded');
});

这没关系,但我不想为每个图像定义一个单独的延迟对象。如果它们有数百个,或者它们可能出现也可能不出现在给定页面上怎么办?我想一次性完成所有操作,例如:

$.when(allImagesHaveLoaded).done(function(){
    console.log('all imgs loaded');
});

我已经尝试创建一个 allImagesHaveLoaded 函数,它迭代图像,为每个图像创建一个新的延迟对象。问题是,如果我返回一个这些数组作为一个 when 的参数,它就不起作用(因为它不是一个延迟对象,它是一个延迟对象数组)。

我也摆弄了一下$.Deferred.pipe(试图创建一个链式延迟对象以传递给when),但这似乎没有帮助。

有没有明智的做法?

【问题讨论】:

  • JOOI - 什么是 $(element).load() ?据我所知,它不在标准 API 中。
  • 它在 jQuery 文档中,here。它只是将回调绑定到加载事件。它不应与执行 ajax 请求的 ajax api load 混淆。
  • 啊,那个!当然 - 我以为你是在触发负载,而不是绑定'onload'回调:)

标签: jquery jquery-deferred


【解决方案1】:

有一种方法可以将延迟对象数组传递给$.when:

$.when.apply($, myArray).done(...);

【讨论】:

  • 这不涉及“不必为每个图像定义单独的延迟对象”。
  • @lonesomeday 确实不是,但我认为没有任何简单的方法可以解决这个问题。另一种方法是根本不使用延迟对象(即使用回调来计算成功加载操作的数量)。
  • 我需要为每个图像定义一个单独的延迟对象并不重要,只要我能够循环它,这样就可以了,谢谢。出于兴趣,它如何/为什么起作用?我在 jQuery 文档中找不到这个...
  • @Spycho apply 通过使用数组调用函数(在本例中为 $.when):该数组的元素用作函数的参数。第一个参数设置上下文(这里是$,jQuery 对象),第二个设置参数。这是一种原生 Javascript 技术,而不是 jQuery 技术。
  • @Spycho 这不是 jQuery 的东西,你可以用 myfunc.apply(ctx, array) 调用 any 函数来表示 ctx.myfunc( array_contents ...)。另请参阅.call。
【解决方案2】:
var imgDefs = $("img").map(function(key, val) {
  var def = $.Deferred();
  $(val).load(def.resolve);
  return def;
}).toArray();

$.when.apply($, imgDefs).done(...);

【讨论】:

    猜你喜欢
    • 2011-08-03
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    相关资源
    最近更新 更多