Reputation: 3380
With the following code I want the li elements to fade in one by one, but the all fade in together:
$('li').each(function () {
$(this).delay(1000).fadeIn(1000);
});
Can anyone explain why they do not fade in one by one?
Upvotes: 0
Views: 3299
Reputation: 340055
The .delay
call doesn't stop the loop from carrying on immediately, so all of the delays and animations will start (pretty much) at once.
The most trivial solution is to stagger the delay by the current index number:
$('li').each(function(index) {
$(this).delay(1000 * index).fadeIn(1000);
});
A better solution would use a pseudo-recursive loop and the "completion callback" of the animation to trigger the next iteration:
var els = $('li').get();
(function loop() {
if (els.length) {
var el = els.shift();
$(el).fadeIn(1000, loop);
}
})();
This method is generally preferable because it ensures that the next fade-in cannot possibly start until the previous has finished, and also avoids creating multiple parallel delay / fade queues (one per element) since the 2nd animation isn't queued until the first has finished.
Upvotes: 2
Reputation: 8233
I guess this is because you basically telling each li
to wait 1 sec and to fade in. So that's what they do :)
Right now, your code is similar to:
$('li').delay(1000).fadeIn(1000);
Try something like that :
var delay = 0;
$('li').each(function () {
$(this).delay(delay).fadeIn(1000);
delay += 1000;
});
Or, as Alnitak suggest, a cleaner way is to use the current index provided by $.each()
:
$('li').each(function (index) {
// index will return the loop index starting to 0
$(this).delay(index*1000).fadeIn(1000);
});
Upvotes: 1
Reputation: 2002
This is a misunderstanding of jQuery.each
. It doesn't mean do it for one, then wait for that to finish before moving on, for that you'd need to use a promise.
Instead, try changing your delay to a multiple of the index of each LI in the array, e.g.:
$('li').each(function(index) {
$(this).delay((index + 1) * 1000).fadeIn(1000);
});
Since array indices always start from 0, and 0 * 1000 = 0, I've added 1 to the index before multiplying by 1000 to ensure the first one happens after 1 second, the second after 2 seconds and so on.
If you don't want a 1s delay to the first li
fading in, then it's simply:
$('li').each(function(index) {
$(this).delay(index * 1000).fadeIn(1000);
});
Upvotes: 0
Reputation: 7579
cause each
is not delayed. Every delay is applied almost at the same time.
you may want to try use the complete
part do fadeIn
the next element
.fadeIn( [duration ] [, complete ] )
Upvotes: 0