【问题标题】:$.each animation running separately$.each 动画单独运行
【发布时间】:2013-12-10 18:50:27
【问题描述】:

我正在尝试一个接一个地运行每个动画功能,而不是一次运行。

这是我目前得到的:

   $(document).ready(function(){ 
        var bars = $('.bar');
        bars.each(function(){
            var widthpercent = $(this).attr("data-percent");
            $(this).fadeIn();
            $(this).animate({width:widthpercent},500);
        });
    });

我尝试过以各种组合方式使用.delay()setTimeout(),但均无济于事。

谁能指出我正确的方向?谢谢!

【问题讨论】:

  • 提示:不要使用$(this).attr('data-percent'),使用$(this).data('percent')。 jQuery 给你一个很好的帮手。
  • 感谢您的提示,我会记住的!
  • @meagar:这也有不利之处。它速度较慢,它将数据解析为 JSON,这并不总是需要,并将数据存储在 jQuery.cache 中,这通常是不必要的。
  • 您希望每个栏一个接一个地加载或淡入淡出/动画?
  • 我希望他们现在一次加载并制作一个动画。所有加载和动画同步

标签: javascript jquery each


【解决方案1】:

在我看来,您正在寻找animatecomplete 函数。您可以编写一个递归函数来继续调用complete 函数中的函数,直到所有项目都被动画化。为了简化:每次动画一个元素时,都会触发一个回调来动画下一个元素。这就是 complete 参数的用途,所以我确定这就是您要寻找的。​​p>

这里有一个示例,您可以根据自己的特定需求进行调整。

Live demo here (click).

var $divs = $('div');

function animate(element) {
  $(element).animate({height: '30px'}, {
    complete: function() {
      if (current < $divs.length-1) {
        ++current;
        animate($divs[current]);
      }
    }
  });
}

var current = 0;
animate($divs[current]);

此外,同样的逻辑可以应用于您的fadeIn。只需将fadeIn 的回调包装在该逻辑周围,如下所示:

Live demo here (click).

var $divs = $('div');

function animate(element) {
  $(element).fadeIn(function() { //now the animation is a callback to the fadeIn
    $(element).animate({height: '70px'}, {
      complete: function() {
        if (current < $divs.length-1) {
          ++current;
          animate($divs[current]);
        }
      }
    });
  });
}

var current = 0;
animate($divs[current]);

这是你的代码:live demo here (click).

$(document).ready(function(){ 

var $divs = $('.bar');

function animate(element) {
  $(element).fadeIn(function() { //you could unwrap this depending on what you're looking for
    var widthpercent = $(element).attr("data-percent");
    $(element).animate({
      width:widthpercent,
      duration: '500ms'
    }, {
      complete: function() {
        if (current < $divs.length-1) {
          ++current;
          animate($divs[current]);
        }
      }
    });
  }); //end fadeIn callback
}

var current = 0;
animate($divs[current]);

});

【讨论】:

  • 这是最好的解决方案,不需要超时
  • 这个答案是(应该是)正确的解决方案。你的意图更清楚,它不依赖于希望超时与动画同步。让动画通过回调告诉您何时完成并收工!
【解决方案2】:

试试这个:

var animate = function (el) {
    return function () {
        var widthpercent = el.data('percent');
        el.fadeIn();
        el.animate({
            width: widthpercent
        }, 500);
    }
}
var bars = $('.bar');
bars.each(function (index) {
    var $this = $(this);
    setTimeout(animate($this), index * 500);
});

Fiddle

【讨论】:

  • 我个人不想依赖多个setTimeout 调用与动画完美同步。可能取决于有多少。
  • @PSL:已经有一个闭包。传递给.each() 的函数会在每次调用时创建一个新的变量作用域,传递给setTimeout 的函数会创建一个该作用域的闭包。
  • @BlueSkies 哦,对了.....但是最好的方法是在每个元素的动画完成时调用一个函数。
  • ...但是如果您确实采用了这种方法,则无需维护 time 变量。您可以使用.each() 给出的计数器,然后执行i * 500
  • @PSL:我同意。我认为这比安排多个超时并希望它们保持同步要安全一些。
【解决方案3】:
$(document).ready(function(){ 
    var bars = $('.bar');
    bars.each(function(i){
        var widthpercent = $(this).attr("data-percent");
        $(this).delay(i*800).animate({width:widthpercent,opacity:1,},500);
    });
});

这将在延迟800 * i 毫秒后进行动画处理。

看到这个JSFiddle example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2018-02-17
    • 2020-01-31
    • 2012-10-08
    相关资源
    最近更新 更多