Animate the Div after the previous Div animation has completed using deferred object
. This simple method works with the two functions f1
and f2
, however when I introduce f3
it fails.
Is there a better way I can achieve this using the 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>
You will find it simpler to :
animationAgent()
into a simple, promise-returning worker function that knows only about the element it animates, and nothing about the sequence in which it is to be used (ie omit prevElement
),f1()
, f2()
and f3()
, to return the promise returned to them by animationAgent()
.Then you have the basis for building 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);
Alternatively, construct the .then chain mechanistically 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());
Or, as the three animations are identical, you can avoid the need for individual functions by constructing the .then chain from an array of element selectors and calling animationAgent()
directly :
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());