Check out this fiddle: http://jsfiddle.net/mattball/nWWSa/
var $lis = $('ul.innerfade > li');
function fadeThemOut()
{
$lis.fadeOut('slow', fadeThemIn);
}
function fadeThemIn()
{
$lis.fadeIn('slow', fadeThemOut);
}
// kick it off
fadeThemOut();
The fading in/out works fine a couple of times, but then starts going very slow. What is the problem? Is this a bug?
The problem is that the callbacks are executed for each element once it is faded in/out, not only when all of them are. So this accumulates a lot of callbacks. It goes like this (lets say we have only two elements, A and B):
At the beginning, the queues are empty:
A:
[]B:
[]Then you call
fadeOuton both elements:A:
[fadeOut]B:
[fadeOut]A fades out:
fadeInis added to both elements.A:
[fadeIn]B:
[fadeOut, fadeIn]Then B fades out: Again,
fadeInis added to both elements.A:
[fadeIn, fadeIn]B:
[fadeIn, fadeIn]A fades in:
fadeOutis added to both elements.A:
[fadeIn, fadeOut]B:
[fadeIn, fadeIn, fadeOut]B fades in: …
A:
[fadeIn, fadeOut, fadeOut]B:
[fadeIn, fadeOut, fadeOut]And so forth. The exact order might differ, but as animations are queued by default, this adds more and more callbacks to the queue.
You can solve this using deferred objects:
DEMO
Now,
fadeThemInis only called when the animation of all elements is completed.Another way would be to change the functions to not work on all elements, but only on the current one:
though it could be that the elements are not in sync then.
DEMO
In your specific case, you could just fade in and out the
ulelement.