4

我有一个在每个 li 中淡入的 for 循环,我想做的是等到最后一个 li 完全淡入,然后继续使用类似于回调的代码,但我不确定如何实现这一点?我在想我可以使用 Deferred 对象吗?

JS

  var newArray = [3,2,6,4,0,1,5];
    for (var i = 0; i < newArray.length; i++) {
      var dfd = $.Deferred();
      $(this).eq(newArray[i]).fadeIn(i * 500);
      dfd.resolve();
      //.. continue with callback code??
    }
4

2 回答 2

6

您可以使用$.when: 通过将所有fadeIn调用中的 Deferreds 传递给它,您可以注册一个回调,以便仅在所有调用完成后才执行:

var deferreds = [];
for (var i = 0; i < newArray.length; i++) {
    var dfd = $(this).eq(newArray[i]).fadeIn(i * 500);
    deferreds.push(dfd);
}
$.when.apply($, deferreds).then(function() { ... });

jsFiddle的工作示例。请注意,您可以将 的返回值fadeIn用作Deferred.

更新:由于您希望每个fadeIn人只最后一个结束后开始,Bergi 的回答可能更合适。另一种选择(更简单,恕我直言)可能是:

var i = 0;
function f() {
    if ( i < newArray.length ) {
        $(this).eq(newArray[i]).fadeIn(i * 500, f);
        i++;
    } else {
        // Your "done" callback, if any
    }
}
f();

工作示例。我坚持使用您的原始代码(每个效果使用不同的持续时间),但如果您希望它们都具有相同的效果,请删除i *并使用500.

于 2012-11-22T14:38:41.003 回答
1

我认为Deferreds在这里不会有很大帮助。当然,您可以.promise()在 jQuery 实例上为每个 [效果] 队列获取一个,并且由于该方法,您甚至可以将 jQuery 对象直接传递给$.when,但我认为回调链 - 对于连续动画,您需要一些链 - 可以更轻松:

function chainedFadeIn($el, order, callback) {
    if (!order.length)
        return callback();
    $el.eq(order.shift()).fadeIn(500, function() {
        chainedFadeIn($el, order, callback); // notice we removed the first element
    }); 
}
chainedFadeIn($(this), [3,2,6,4,0,1,5], function() {
    // do something
});

带有 Promises 的替代版本:

function getFadeInChain($el, order) {
    if (!order.length)
        return order; // or anything else
    return $el
      .eq(order.shift())
      .fadeIn(500)
      .promise()
      .then(getFadeInChain.bind(null, $el, order));
}
getFadeInChain($(this), [3,2,6,4,0,1,5]).done(function() {
    // do something
});

jsfiddle.net 上的演示:回调延迟

于 2012-11-22T16:00:21.963 回答