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:すべての呼び出しからDeferredを渡すことにより、fadeInすべてが完了したときにのみ実行されるコールバックを登録できます。

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

更新:最後の1つが終了したfadeInにのみそれぞれを開始するようにしたいので、 Bergiの答えがより適切かもしれません。別の方法(より単純なIMHO)は次のようになります。

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 インスタンスで for every [effect] キューを取得できます。そのメソッドのおかげで、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
});

Promise を使用した代替バージョン:

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 のデモ: callbacksDeferred

于 2012-11-22T16:00:21.963 に答える