15

3 つの div があり、前の div が完了したらそれぞれをアニメーション化したいとします。現在、私はこれを書いています:

$('div1').fadeOut('slow', function() {
    $('div2').fadeOut('slow', function() {
        $('div3').fadeOut('slow');
    });
});

これは醜いですが、扱いやすいです。

ここで、さまざまな要素で次々に発生する必要がある 10 個の異なるアニメーションがあるとします。突然、コードが非常に扱いにくくなり、管理が非常に難しくなります...

私がやろうとしていることの擬似コードは次のとおりです。

$('div1').fadeOut('slow' { delay_next_function_until_done: true } );
$('div2').fadeOut('slow' { delay_next_function_until_done: true } );
$('div3').animate({ top: 500 }, 1000 );

どうすればこれを達成できますか?

4

7 に答える 7

22

jQuery の最近のバージョンを使用している場合は、アニメーションの promise を使用します。

$('div1').fadeOut('slow').promise().pipe(function() {
    return $('div2').fadeOut('slow');
}).pipe(function() {
    return $('div3').animate({ top: 500 }, 1000 );
});

ジェネリックにすることができます:

$.chain = function() {
    var promise = $.Deferred().resolve().promise();
    jQuery.each( arguments, function() {
        promise = promise.pipe( this );
    });
    return promise;
};

var animations = $.chain(function() {
    return $('div1').fadeOut('slow');
}, function() {
    return $('div2').fadeOut('slow');
}, function() {
    return $('div3').animate({ top: 500 }, 1000 );
});

$.when( animations ).done(function() {
    // ALL ANIMATIONS HAVE BEEN DONE IN SEQUENCE
});

まだまだ多くの関数クロージャがありますが、それが Javascript の本質です。ただし、コールバックの「開始」を回避するため、Deferreds/Promises を使用する方がはるかに自然で柔軟性があります。

于 2012-04-29T10:39:58.703 に答える
4

私はそうします。この方法では、リスト変数の要素を追加または削除するだけで、すべてのdivを好きなように配置できます。また、それらを並べ替えることができ、遅延時間を気にする必要はありません。

var list = [ '#div1', '#div2', '...' ];
var i = 0;
function fade(cb) {
    if (i < list.length) {
        $(list[i]).fadeOut('slow', function() {
            i++;
            fade(cb);
        });
    } else {
        cb && cb();
    }
}
fade();

プロセスの終了時にコールバックを追加することもできます

fade(function(){alert('end')});

デモ

于 2012-04-29T07:28:35.910 に答える
3

完了関数またはコールバックがネストされすぎたり、コードが何度も繰り返されたりする場合は、共通の関数を使用したデータテーブルソリューションについて考える傾向があります。

function fadeSequence(list) {
    var index = 0;
    function next() {
        if (index < list.length) {
            $(list[index++]).fadeOut(next);
    }
    next();
}

var fades = ["div1", "div2", "div3", "div4", "div5"];
fadeSequence(fades);

また、一部のアイテムに異なるタイプのアニメーションが必要な場合は、連続する各アニメーションがどうあるべきかを説明するオブジェクトの配列を作成できます。オブジェクトの配列には、必要なだけ詳細を入れることができます。次のように、アニメーションを他の同期jQueryメソッド呼び出しと混合することもできます。

function runSequence(list) {
    var index = 0;
    function next() {
        var item, obj, args;
        if (index < list.length) {
            item = list[index++];
            obj = $(item.sel);
            args = item.args.slice(0);
            if (item.sync) {
                obj[item.type].apply(obj, args);
                setTimeout(next, 1);
            } else {
                args.push(next);
                obj[item.type].apply(obj, args);
            }
        }
    }
    next();
}

// sequence of animation commands to run, one after the other
var commands = [
    {sel: "#div2", type: "animate", args: [{ width: 300}, 1000]},
    {sel: "#div2", type: "animate", args: [{ width: 25}, 1000]},
    {sel: "#div2", type: "fadeOut", args: ["slow"]},
    {sel: "#div3", type: "animate", args: [{ height: 300}, 1000]},
    {sel: "#div3", type: "animate", args: [{ height: 25}, 1000]},
    {sel: "#div3", type: "fadeOut", args: ["slow"]},
    {sel: "#div4", type: "fadeOut", args: ["slow"]},
    {sel: "#div1", type: "fadeOut", args: ["slow"]},
    {sel: "#div5", type: "css", args: ["position", "absolute"], sync: true},
    {sel: "#div5", type: "animate", args: [{ top: 500}, 1000]}
];
runSequence(commands);

そして、これがこの2番目のオプションの実用的なデモです:http://jsfiddle.net/jfriend00/PEVEh/

于 2012-04-29T07:29:11.477 に答える
2

これを行う 1 つの方法は、次のように独自のヘルパー関数を作成することです。

$.fn.sequentialFade = function() {
    if(this.length > 0) {
        var $set = $(this);
        $set.eq(0).fadeOut(function() {
            $set.slice(1).sequentialFade();
        });
    }
}

そして、次のように使用します。

$('.div1, .div2. .div3').sequentialFade();

http://jsfiddle.net/JpNgv/

于 2012-04-29T07:01:57.107 に答える
1

次のようなものを試してください:

$( 'div1' ).fadeOut();
$( 'div2' ).delay( 500  ).fadeOut();
$( 'div3' ).delay( 1000 ).fadeOut();

必要に応じてタイミングを調整します

于 2012-04-29T06:53:03.980 に答える
1

これを使って:

$('#div1, #div2, #div3').each(function(index){
    $(this).delay(1000 * index).hide(1000);
});

<div>sa クラスを指定できる場合:

$('.forHide').each(function(index, value){
    $(this).delay(1000 * index).hide(1000);
});​
  • 最初の要素は 1000 * 0 = 1 秒のアニメーションですぐにフェードアウトします。
  • 2 番目の要素は 1000 * 1 = 1 秒後に 1 秒のアニメーションでフェードアウトします。
  • 3 番目の要素は、1 秒のアニメーションで1000 * 2 = 2 秒後にフェードアウトします。
  • ...
  • ...
  • n要素は、1 秒のアニメーションで1000 * n = n 秒後にフェードインします。

ライブデモ

于 2012-04-29T06:53:56.410 に答える
1

コールバックは友達です。押しのけてはいけません。それらを単純化する方法があります。ここにそれらの1つがあります

$('div1').fadeOut('slow', div2)
function div3() { $('div3').fadeOut('slow'); }
function div2() { $('div2').fadeOut('slow', div3); }
于 2012-04-29T06:58:21.040 に答える