One Div animation after another using a deferred object

Div animation after completing a previous div animation using a deferred object . This simple method works with the two functions f1 and f2 ; however, when you enter f3 it fails.

Is there a better way to achieve this using a deferred object?

JSFiddle: https://jsfiddle.net/j0bgzjvd/

 var deferred = $.Deferred(); function animationAgent(element, prevElement) { $(prevElement).promise().done( function () { return $(element).css("display", "block").animate({width:360},2000, "linear") }); } function f1() { animationAgent("#div1"); } function f2() { animationAgent("#div2", "#div1"); } function f3() { animationAgent("#div3", "#div2"); } deferred.resolve(); deferred.done( [ f1, f2, f3 ] ); 
 div { width: 200px; height: 200px; background-color: red; margin-bottom: 10px; display: none; } 
 <script src="https://code.jquery.com/jquery-1.10.2.js"></script> <div id="div1"></div> <div id="div2"></div> <div id="div3"></div> 
+8
javascript jquery deferred jquery-deferred
source share
3 answers

It will be easier for you:

  • make animationAgent() simple by promising a returning working function that knows only about the element that it animates, and nothing about the sequence in which it should be used (i.e. omit prevElement ),
  • we organize the functions f1() , f2() and f3() to return the promise returned by him, animationAgent() .

Then you have the basis for creating a reliable animation sequence.

 function animationAgent(element) { return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise(); } function f1() { return animationAgent("#div1"); } function f2() { return animationAgent("#div2"); } function f3() { return animationAgent("#div3"); } f1().then(f2).then(f3); 

Demo

Alternatively, mechanically build a .then chain from an array of function references:

 function animationAgent(element) { return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise(); } function f1() { return animationAgent("#div1"); } function f2() { return animationAgent("#div2"); } function f3() { return animationAgent("#div3"); } [f1, f2, f3].reduce(function(promise, fn) { return promise.then(function() { return fn(); }); }, $.when()); 

Demo

Or, since the three animations are identical, you can avoid the need for separate functions by building a .then chain from an array of element selectors and directly calling animationAgent() :

 function animationAgent(element) { return $(element).css("display", "block").animate({width:360}, 2000, "linear").promise(); } ['#div1', '#div2', '#div3'].reduce(function(promise, selector) { return promise.then(function() { return animationAgent(selector); }); }, $.when()); 

Demo

+1
source share

Ever thought of using callbacks in an animated function?

Here is an example with fadeOut: https://jsfiddle.net/0r7e2wco/

 fadeOutInTurn([ $("#div1"), $("#div2"), $("#div3"), $("#div4"), ]); //Fades out elements one after another function fadeOutInTurn(elements) { var x = 0; function animate() { $(elements[x]).fadeOut(3000, function() { if(x < elements.length - 1) { x++; animate(); } }); } animate(); } 
0
source share

not sure, but I think this is what you want.

fiddle working example

I think you are hoping deferred.done() will execute f1, f2, f3 one by one, and it will do it. but it does not wait for the animation called inside these functions to complete before the next function is called.

try registering function calls to the console using console.log() and you will find out.

here is the updated javascript code -

 var deferred = $.Deferred(); var lock = 1; function animationAgent(element, id, prevElement) { var interval; var flag = 0; if (id != lock) { interval = setInterval(function() { if (id == lock) { clearInterval(interval); animationAgent(element, id, prevElement); } }, 1000); }else{ $(prevElement).promise().done(function() { lock++; return $(element).css("display", "block").animate({ width: 360 }, 2000, "linear"); }); } } function f1() { return animationAgent("#div1", 1); } function f2() { return animationAgent("#div2", 2, "#div1"); } function f3() { return animationAgent("#div3", 3, "#div2"); } deferred.resolve(); deferred.done([f1, f2, f3]); 
0
source share

All Articles