user3077147
user3077147

Reputation: 195

How can I make the animations be run one by one?

The HTML code:

<ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
</ul>

The js code:

<script type="text/javascript">
$(document).ready(function() {
    var lis = $("li");
    for (var i = 0; i < lis.length; i++) {
        $(lis[i]).animate({opacity: 0}, 1000);
    }
});
</script>

I just find that the lis will disappear together. How can I do that they will disappear one by one?

Upvotes: 13

Views: 2600

Answers (5)

A. Wolff
A. Wolff

Reputation: 74420

You could instead use CSS animation/transition and relevant transitionEnd event with following logic:

$(function() {
  var events = [
    "webkitTransitionEnd",
    "oTransitionEnd",
    "otransitionend",
    "MSTransitionEnd",
    "transitionend"
  ];


  $("li").on(events.join(" "), function(e) {
    $(this).next().addClass('animated');
  }).first().addClass('animated');
});
li {
  opacity: 1;
  -webkit-transition: opacity 1s;
  -moz-transition: opacity 1s;
  -ms-transition: opacity 1s;
  -o-transition: opacity 1s;
  transition: opacity 1s;
}
li.animated {
  opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

<ul>
  <li>a</li>
  <li>b</li>
  <li>c</li>
  <li>d</li>
  <li>e</li>
</ul>

-DEMO jsFiddle-

Upvotes: 1

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

Sorry for joining the party late.

The existing answers have issues when a timer blocks and rely on the accuracy of timers, moreover they require an actual delay.

jQuery actually provides a generic way to perform animations sequentially with promises:

$(document).ready(function() {
    var lis = $("li");
    var queue = $.Deferred().resolve(); // create an empty queue
    lis.get().forEach(function(li){
        queue = queue.then(function(){
           return $(li).animate({opacity: 0}, 1000).promise();
        })
    });
});

Fiddle

Note that this will work even if you assign them different animation durations or different animations, the result in queue will contain a hook on when the last animation finished. This also supports aggregations (waiting for all promises to finish in parallel) and more.

Upvotes: 11

Sadikhasan
Sadikhasan

Reputation: 18600

You can use delay() function

for (var i = 0; i < lis.length; i++) {
    $(lis[i]).delay(i * 400).animate({opacity: 0}, 1000);
              ^^^^^^^^^^^^^^
}

JS Fiddle

Upvotes: 1

jogesh_pi
jogesh_pi

Reputation: 9782

use delay()

$(lis[i]).delay(i * 500).animate({opacity: 0}, 1000);

DEMO

Upvotes: 5

nnnnnn
nnnnnn

Reputation: 150030

Each element has its own animation queue, so as you've seen they all animate at the same time rather than waiting for the previous element to finish. You can add a delay for each element:

$(lis[i]).delay(i*1000).animate({opacity: 0}, 1000);
// ------^^^^^^^^^^^^^^

Demo: http://jsfiddle.net/p2kdpxr3/

Upvotes: 8

Related Questions