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>
When the request is complete, the deferred is resolved (with defer.resolve ); if an error occurs, the deferred is rejected (with defer.reject ). If the promise already exists, the callback is attached to the existing deferred; otherwise, the promise is first created and then the callback is attached.
There are several approaches to animating inside a div that can stretch your skills. To get the broadest support we can’t rely on CSS alone right now, though we can still get pretty far.
This JQuery.Deferred () method in JQuery is a function which returns the utility object with methods which can register multiple callbacks to queues. It calls the callback queues, and relay the success or failure state of any synchronous or asynchronous function.
Creating an overlay effect for two <div> elements can be easily done with CSS. This can be done with the combination of the CSS position and z-index properties. The z-index of an element defines its order inside a stacking context.
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);
DEMO
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());
DEMO
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());
DEMO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With