Not a nested animation sequence in jQuery?

I am trying to create an animation sequence with jQuery where one animation starts after the previous one. But I just can’t wrap my head around me. I tried using jQuery.queue, but I don’t think I can use it because it seems to have one separate queue for each element of the jQuery array.

I need something like:

$('li.some').each(function(){ // Add to queue $(this).animate({ width: '+=100' }, 'fast', function(){ // Remove from queue // Start next animation }); }); 

Is there a jQuery way to do this, or do I need to write and process my own queue manually?

+6
source share
5 answers

You can create custom .queue() to avoid unlimited nesting.

 var q = $({}); function animToQueue(theQueue, selector, animationprops) { theQueue.queue(function(next) { $(selector).animate(animationprops, next); }); } // usage animToQueue(q, '#first', {width: '+=100'}); animToQueue(q, '#second', {height: '+=100'}); animToQueue(q, '#second', {width: '-=50'}); animToQueue(q, '#first', {height: '-=50'}); 

Demo at http://jsfiddle.net/gaby/qDbRm/2/


If, on the other hand, you want to perform the same animation for multiple elements one by one, you can use their index for .delay() each element of the animation throughout all the previous ones.

 $('li.some').each(function(idx){ var duration = 500; $(this).delay(duration*idx).animate({ width: '+=100' }, duration); }); 

Demo at http://jsfiddle.net/gaby/qDbRm/3/

+16
source

The .animate () callback actually accepts another .animate (), so all you would need to do would be

  $(this).animate({ width: '+=100' }, 'fast', function(){ $(selector).animate({attr: val}, 'speed', function(){ }); }); 

etc.

+2
source

You can call the following recursively.

 function animate(item) { var elem = $('li.some').eq(item); if(elem.length) { elem.animate({ width: '+=100' }, 'fast', function() { animate(item + 1); }); } } animate(0); 
+1
source

Why not create a queue?

 var interval = 0; //time for each animation var speed = 200; $('li.some').each(function(){ interval++; $(this).delay(interval * speed).animate({ width: '+=100' }, speed); }); 

EDIT: speed parameter added

+1
source

Thanks everyone!

I thought I should share the results of my question. Here is a simple jQuery slideDownAll plugin that crawls one element at a time, not immediately.

 (function ($) { 'use strict'; $.fn.slideDownAll = function (duration, callback) { var that = this, size = this.length, animationQueue = $({}); var addToAnimationQueue = function (element, duration, easing, callback) { animationQueue.queue(function (next) { $(element).slideDown(duration, easing, function () { if (typeof callback === 'function') { callback.call(this); } next(); }); }); }; return this.each(function (index) { var complete = null, easing = 'linear'; if (index + 1 === size) { complete = callback; easing = 'swing'; } addToAnimationQueue(this, duration / size, easing, complete); }); }; } (jQuery)); 

Not a very good test, but anyway.

Enjoy it!

+1
source

Source: https://habr.com/ru/post/893587/


All Articles