twinturbotom
twinturbotom

Reputation: 1544

Javascript and jQuery: iterate through an array but wait for animations to finish

I have a simple example with several boxes to move across the screen. Each box shouldn't move until the previous one completes. I have a working solution using .shift() but I should be able to iterate through this using a for-loop and $.each. Anyone know how to get the for and $.each to work?

fiddle here the shift button works the way I would like it to.

Thanks.

JS:

boxes = [
  ['.box0', 'animate', [ {left: '200px' }, 1000 ] ],
  ['.box1', 'animate', [ {left: '200px' }, 1000 ] ],
  ['.box2', 'animate', [ {left: '200px' }, 1000 ] ],
  ['.box3', 'animate', [ {left: '200px' }, 1000 ] ],
  ['.box4', 'animate', [ {left: '200px' }, 1000 ] ],
  ['div', 'animate', [ {left: '0px' }, 1000 ] ]
];
$('.eachMethod').click(animEach);
$('.ifMethod').click(animFor);
$('.shiftMethod').click(animShift);
function animEach(){
  $.each(boxes, function(){
    $.fn[this[1]].apply($(this[0]), this[2]).promise().done();
  });
};
function animFor(){
  for (i=0; i < boxes.length; i++) {
    b=boxes[i];
    $.fn[b[1]].apply($(b[0]), b[2]).promise().done();
  }
};
function animShift(){
  b = boxes.shift();
  if (b) {
    $.fn[b[1]].apply($(b[0]), b[2]).promise().done(animShift);
  }
};​

HTML:

<ul>
  <li><button class='eachMethod'>$.each</button></li>
  <li><button class='ifMethod'>if</button></li>
  <li><button class='shiftMethod'>shift</button></li>
</ul>
<div class='box0'></div>
<div class='box1'></div>
<div class='box2'></div>
<div class='box3'></div>
<div class='box4'></div>​

CSS:

div{
 clear: both;   
 background-color: green;
 width: 40px;
 height: 40px;
 Position: relative;    
}
ul li {
  float: left;
}

Upvotes: 1

Views: 362

Answers (1)

charlietfl
charlietfl

Reputation: 171679

animate() is asynchronous, so the loops will complete in a few milliseconds invoking the animation on each element virtually simultaneously. Your .promise().done() is not doing anything when you use the loops.

The version using animShift() is only applying the animation to one element at a time, and since the next call is within done() it won't fire until the first animation is complete

Upvotes: 1

Related Questions