jQuery / Javascript:等待动画完成

时间:2012-11-27 17:48:46

标签: javascript jquery

让我先说明我是Javascript的新手,但不是编程。我在jQuery对象上调用fadeOut,如:

$(x).fadeOut('fast');

我还有其他东西会逐渐消失,但是我需要他们互相等待,而且我不一定知道会有多少人会这样做。 x是一个数组中的字符串,其中包含淡入或淡出的项。在我的第一次尝试中,我使用fadeOut中的回调函数,如下所示:

$(x).fadeOut('fast', function(){ foo(modifiedArray); })

foo是我想要的方法,而modifiedArray是减去x的数组。这仍然没有让它等待,所以接下来我尝试了:

$(x).fadeOut('fast');
while( $(x).css('display') != 'none' ){}
foo(modifiedArray);

但循环永远不会结束。在再次拨打foo(modifiedArray)之前,如何让动画等待?

编辑:这是完整的代码

function animateElements(elements){
if (elements.length == 1){
    var x = elements[0];
    $(x).fadeIn('slow');
}
else{
    var x = elements.pop();
    $(x).fadeOut('fast');
    while(  $(x).css('display') != 'none' ){}
    animateElements(elements);
}
}

4 个答案:

答案 0 :(得分:3)

见这里:http://jsfiddle.net/3cn3z/3/

function sequentialFade(items, duration) {
    var arr = 'shift' in items ? items : items.get();
    var item = arr.shift();

    $(item).fadeOut(duration, function(){
        sequentialFade(arr, duration);
    });
}

sequentialFade($("div"), "slow");

如果你觉得这需要解释,请告诉我。

这也可以写成一个小的jQuery插件,如:http://jsfiddle.net/3cn3z/1/

(function($) {
    $.fn.seqFade = function(duration) {
        var items = this.get();

        (function fadeStep(){
            var item = items.shift();
            $(item).fadeOut(duration, fadeStep);
        })();

        return this;
    };
})(jQuery);

并使用如下:

$("div").seqFade("slow");

为了更进一步,我们可以将插件概括为使用任何内置的jQuery动画函数:http://jsfiddle.net/3cn3z/5/

(function($) {
    $.fn.seqAnim = function(animFunc, duration, callback) {
        var items = this.get();
        var me = this;
        (function animStep(){
            var item = items.shift();

            if (item == undefined && callback != undefined)
                callback.call(me)
            else
                $(item)[animFunc](duration, animStep);
        })();

        return me;
    };
})(jQuery);

用过:

$("div").delay(500).seqAnim("slideToggle", "slow", function(){
    this.delay(500).seqAnim("fadeIn", 500);
});

答案 1 :(得分:1)

将您的代码更正为:

    function animateElements(elements) {
        if (elements.length == 1) {
            var x = elements[0];
            $(x).fadeOut('slow');  // Should this be fade out?
        }
        else {
            var x = elements.pop();
            $(x).fadeOut('slow', function () { animateElements(elements) });
        }
    }

您的代码有三个问题。首先,您使用的是循环而不是回调函数。其次,回调函数需要是一个函数 - 即使它是匿名的。第三,FadeIn()时,您fadeOut()代替length == 1

答案 2 :(得分:1)

为了完整起见。在您的代码中,您可以修复以下内容。

  1. 使用.fadeIn()代替.fadeOut()

    $(x).fadeIn('slow');
      ---^---
    
  2. 您可能希望使用.shift()代替.pop()从左到右,而不是从右到左遍历数组。

    var x = elements.pop();
                  ---^---
    
  3. .fadeOut()的完整回调中调用递归步骤,避免强制检查元素的样式。

    $(x).fadeOut('fast');
      ---^---
    while(  $(x).css('display') != 'none' ){}
    animateElements(elements);
    
  4. 使用elements.length == 0作为基本案例。这将提高可读性。

    if (elements.length == 1) {
      --^--
    
  5. 最后,代码如下所示:

    function animateElements(elements) {
      if (elements.length) {
        var x = elements.shift();
        $(x).fadeOut('fast', function(){
          animateElements(elements);
        });
      }
    }
    

    See it live

答案 3 :(得分:0)

试试这个:

function animateElements(elements) {
    if (elements.length == 1) {
        var x = elements[0];
        $(x).fadeIn('slow');
    }
    else {
        var x = elements.pop();
        $(x).fadeOut('fast', function() {
            animateElements(elements);
        });
    }
}

DEMO HERE