使用$ .deferred等待多个元素的动画

时间:2012-05-17 13:58:34

标签: jquery animation jquery-deferred

我有这样的代码:

for(i=0;i<somevalue;i++){
   $(".elem[order='"+i+"']").delay(i*duration).animate({opacity:0},duration);
}

当最后一项动画完成时,我想执行

$( “ELEM。”)除去();

我目前正在使用

执行此操作
$(".elem[order='"+i+"']").animate({opacity:0},duration,
function(){
    if(i==somevalue-1){
        $(".elem").remove();
    }
});

但我怎么能用$ .Deferred做到这一点?我正在学习jQuery Deferred's,我无法解决这个问题。

2 个答案:

答案 0 :(得分:1)

更新2:

以下是使用$ .Deferred:

的工作示例
<html>
    <head>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                $.Deferred(function (defer) {
                    var i;
                    var duration = 1000;

                    var pipe = function(defer, index, duration) {
                        return defer.pipe(function () {
                            return $(".elem[order='" + index + "']").animate({opacity: 0}, duration);
                        });
                    };

                    defer.resolve();

                    for (i = 0; i < 5; i++) {
                        defer = pipe(defer, i, duration);
                    }

                    defer.done(function () {
                        console.log("Done, removing all .elem");
                        $(".elem").remove();
                    });
                });
            });
        </script>
        <style type="text/css">
            body { padding: 20px; }
            .elem { border: 1px solid #000; padding: 10px; opacity: 1.0; }
        </style>
    </head>
    <body>
        <div class="elem" order="0">elem 0</div>
        <div class="elem" order="1">elem 1</div>
        <div class="elem" order="2">elem 2</div>
        <div class="elem" order="3">elem 3</div>
        <div class="elem" order="4">elem 4</div>
    </body>
</html>

更新1,基于新介绍的延迟

要回答下面的评论,我认为最好的办法是简单地触发上次触发动画的回调。由于您完全控制决定持续时间(即它不是随机生成的持续时间),因此您可以计算最后一个持续时间,并使用它来确定它是否是正确的迭代来触发回调:< / p>

var i, callback, delay;
var onComplete = function () {
    console.log("Animations complete!");
};
for (i = 0; i < somevalue; i++) {
    delay = i * duration;
    callback = delay === ((somevalue - 1) * duration) ? onComplete : $.noop;
    //callback = i === somevalue - 1 ? onComplete : $.noop; //this can work too but doesn't check duration
    $(".elem[order='" + i + "']").delay(delay).animate({opacity:0}, duration, callback);
}

原始答案

看起来您希望所有这些元素同时开始制作动画,并且具有相同的持续时间。基于此,我建议做一个动画调用,并修改你收集元素集合的方法。

示例:

var i, elements, selector;

for (i = 0; i < somevalue; i++) {
    selector = ".elem[order='" + i + "']";
    if (i === 0) {
        // Start the collection up with the first element
        elements = $(selector);
    } else {
        // Append element to the collection
        elements.add(selector);
    }
}

// Fire up the animation on all elements
elements.animate({opacity:0}, duration, function () {
    console.log("Animation complete!");
});

我实际上没有运行此代码,但我非常有信心它应该可以运行。

答案 1 :(得分:0)

你必须声明变量数据类型,如var i。

for(var i=0;i<somevalue;i++){
   $(".elem[order='"+i+"']).animate({opacity:0},duration);
}