简体   繁体   中英

Jquery chaining animation with each()

i am making an animation with every item element inside the list. My goal is when each item finish the animate function, the next item start to animate and so on. Right now, all i did is all the items run animate function at the same time. The list of item should have hundred of items, i just demonstrate 3 items.

 $(document).ready(function() { $('.list-item').each(function(){ var _this = $(this); _this.find(".loading").animate({ width: "100%" }, 2500); }); }) 
 .list-item .item { position: relative; } .list-item .item { padding: 20px; margin-bottom:10px; } .list-item .item .loading { position: absolute; top: 0; left: 0; bottom: 0; width: 0; background: lightblue; opacity: 0.3; -webkit-transition: none !important; transition: none !important; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="list-item"> <div class="item"> Item 1 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 2 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 3 <span class="loading">&nbsp;</span> </div> </div> 

You can use setTimeout() with a dynamique delay to achieve that

 $(document).ready(function() { var delay = 0; $('.list-item .loading').each(function() { var _this = $(this); setTimeout(function() { _this.animate({ width: "100%" }, 2500); }, delay) delay += 2500; }); }) 
 .list-item .item { position: relative; } .list-item .item { padding: 20px; margin-bottom: 10px; } .list-item .item .loading { position: absolute; top: 0; left: 0; bottom: 0; width: 0; background: lightblue; opacity: 0.3; -webkit-transition: none !important; transition: none !important; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="list-item"> <div class="item"> Item 1 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 2 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 3 <span class="loading">&nbsp;</span> </div> </div> 

You can do it using promise :

$(document).ready(function() {
   var queue = $.Deferred().resolve(); 
      $('.list-item').find(".loading").each(function(){
        var _this = $(this);
        queue = queue.then(function(){
           return _this.animate({width: "100%"}, 2500).promise();
        })
    });
  });

DEMO: https://codepen.io/creativedev/pen/dKqOja

You can use the complete callback-function of the animate to run the next loading sequence:

 $(document).ready(function() { var animate = function($this) { $this.find(".loading").animate({ width: "100%" }, 2500, function() { var $next = $this.next(); if ($next.length > 0) { animate($next); } }); }; animate($('.item').first()); }) 
 .list-item .item { position: relative; } .list-item .item { padding: 20px; margin-bottom:10px; } .list-item .item .loading { position: absolute; top: 0; left: 0; bottom: 0; width: 0; background: lightblue; opacity: 0.3; -webkit-transition: none !important; transition: none !important; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="list-item"> <div class="item"> Item 1 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 2 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 3 <span class="loading">&nbsp;</span> </div> </div> 

If you have exact number of items to animate and defined delay - you can set setTimout to call each animation in exact time (when previous already completed)

 $(document).ready(function() { $('.item').each(function(i){ setTimeout(function() { $(this).find(".loading").animate({ width: "100%" }, 2500); }.bind(this), i * 2500); }); }) 
 .list-item .item { position: relative; } .list-item .item { padding: 20px; margin-bottom:10px; } .list-item .item .loading { position: absolute; top: 0; left: 0; bottom: 0; width: 0; background: lightblue; opacity: 0.3; -webkit-transition: none !important; transition: none !important; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="list-item"> <div class="item"> Item 1 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 2 <span class="loading">&nbsp;</span> </div> <div class="item"> Item 3 <span class="loading">&nbsp;</span> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM