0

让我先说我是 Javascript 新手,而不是编程新手。我调用fadeOut这样的 jQuery 对象:

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

我还有其他事情会淡出淡出,但我需要它们相互等待,我不一定知道有多少人会这样做。x是来自数组的字符串,其中包含淡入或淡出的项目。在我的第一次尝试中,我fadeOut像这样使用了回调函数:

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

我想要的方法在哪里foo, modifiedArray 是数组 minus 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

4 回答 4

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);
});

​</p>

于 2012-11-27T17:58:22.070 回答
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()when length == 1

于 2012-11-27T18:12:16.380 回答
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) {
      --^--
    

最后,代码将如下所示:

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

现场观看

于 2012-11-27T18:12:36.973 回答
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);
        });
    }
}

在这里演示

于 2012-11-27T18:25:01.473 回答