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) {
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!");
});The myAnimate function returns are jQuery promise object. You can then group the two promise objects using $.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.