$.each animation running separately

2019-05-09 23:05发布

问题:

I'm trying to run each animation function one after the other instead of all at once.

This is what I've got so far:

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

I've tried using .delay() and setTimeout() in various combinations to no avail.

Could anyone point me in the right direction? Thank you!

回答1:

It sounds to me like you're looking for animate's complete function. You can write a recursive function to keep calling the function in the complete function until all the items have been animated. To simplify: every time one element is animated, a callback is fired that animates the next element. That is the purpose of the complete parameter, so I'm certain that is what you're looking for.

Here's an example you can adapt to your specific needs.

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

Further, this same logic can be applied to your fadeIn. Just wrap fadeIn's callback around that logic, like this:

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

And here's your code: 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:

Try this:

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



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

This will animate after delaying 800 * i milliseconds.

See this JSFiddle example.