Imagine you are animating several elements on you page. You can use deferred objects to add a completion handler to all of them in a clean way. (jQuery actually does this very well already - see below - but let's use this as an example.)
First let's load jQuery and add two div's to animate:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script>Then add this Javascript code:
<div id="div1" style="background:red; width: 40px; height: 40px;"></div>
<div id="div2" style="background:green; width: 40px; height: 40px;"></div>
function myAnimate(element, css, duration) {The myAnimate function returns are jQuery promise object. You can then group the two promise objects using
var deferred = $.Deferred();
$(element).animate(css, {
duration: duration,
complete: function () {
deferred.resolve();
}
});
return deferred.promise();
}
var animation1 = myAnimate("#div1", {
"width": "200px"
},
500);
var animation2 = myAnimate("#div2", {
"width": "200px"
},
1500);
$.when(animation1, animation2).then(function () {
$("#div1").html("Both done!");
});
$.when
.Inside the myAnimate function we create a new deferred object using
$.Deferred
, do the actual animation and return a promise object (using .promise
to generate the promise object).In the animation complete handler we then resolve the deferred object. This triggers the any
.done
handlers attached to the promise object which are used by $.when
to decide whether to call the $.then
handler function.Rejecting a deferred object
Calling.resolve
indicates that the action has been completed successfully. If for some reason there is an error and the $.then
handler code depends on it you can call .reject
on the deferred object instead. This will trigger .fail
on the promise and the success trigger passed to $.then
will not be executed. You can however pass a function as a second argument to $.then
that will be run on rejection.jQuery already has functionality built in for waiting for several animations to finish
So don't use the example above, use this instead:$("#div1").animate({
"width": "200px"
}, {
duration: 500
});
$("#div2").animate({
"width": "200px"
}, {
duration: 1500
});
$("#div1, #div2").promise().done(function () {
$("#div1").html("Both done!");
});
.animate
does not return a promise object and returns a jQuery object to maintain chainability. You can obtain a promise object for the animations by calling .promise
on the jQuery object.