I have a for loop which fades in each li, what I want to do is wait until the very last li has fully faded in and then continue with the code similar to a callback but I'm unsure how to achieve this? I was thinking that I could possibly use a Deferred object?
JS
var newArray = [3,2,6,4,0,1,5];
for (var i = 0; i < newArray.length; i++) {
var dfd = $.Deferred();
$(this).eq(newArray[i]).fadeIn(i * 500);
dfd.resolve();
//.. continue with callback code??
}
You can use $.when
: by passing the Deferreds from all your fadeIn
calls to it, you can register a callback to be executed only when all of them are done:
var deferreds = [];
for (var i = 0; i < newArray.length; i++) {
var dfd = $(this).eq(newArray[i]).fadeIn(i * 500);
deferreds.push(dfd);
}
$.when.apply($, deferreds).then(function() { ... });
Working example at jsFiddle . Note that you can use the return value of fadeIn
as a Deferred
.
Update: since you want each fadeIn
to start only after the last one ended, Bergi's answer might be more appropriate. An alternative (simpler, IMHO) could be:
var i = 0;
function f() {
if ( i < newArray.length ) {
$(this).eq(newArray[i]).fadeIn(i * 500, f);
i++;
} else {
// Your "done" callback, if any
}
}
f();
Working example . I stuck to your original code (each effect using a different duration), but if you want all them to have the same one, remove the i *
and just use 500
.
I don't think Deferreds will be of great help here. Surely, you can get a .promise()
for every [effect] queue on jQuery instances, and because of that method you could even pass jQuery objects right into $.when
, but I think a callback chain - and for successive animations you need some chain - can do it easier:
function chainedFadeIn($el, order, callback) {
if (!order.length)
return callback();
$el.eq(order.shift()).fadeIn(500, function() {
chainedFadeIn($el, order, callback); // notice we removed the first element
});
}
chainedFadeIn($(this), [3,2,6,4,0,1,5], function() {
// do something
});
Alternative version with Promises:
function getFadeInChain($el, order) {
if (!order.length)
return order; // or anything else
return $el
.eq(order.shift())
.fadeIn(500)
.promise()
.then(getFadeInChain.bind(null, $el, order));
}
getFadeInChain($(this), [3,2,6,4,0,1,5]).done(function() {
// do something
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.