Quick Tip: Easy Sequential Animations in jQuery
In this video quick tip, I’ll demonstrate an easy way to allow for sequential animations of an infinite number of elements. I originally learned this technique from Dave Methvin, but don’t think that many people are aware of this neat little trick.
The Goal
We want to filter through an infinite number of elements on a page, matching some selector, and then make them sequentially fade out.
The HTML
<body> <p>Watch</p> <p>Me</p> <p>Disappear</p> </body>
The jQuery
var paras = $('p'),
i = 0;
// If using jQuery 1.4, you don't need to do || [].
(function() {
$(paras[i++] || []).fadeOut('slow', arguments.callee);
})();
We begin by “caching” all of the paragraphs on the page, wrapped in the jQuery object (var paras). We also create an iterator variable – i. This iterator will allows us to target each new paragraph element, without knowing the specific length of the paras object ahead of time.
Within the self-invoking anonymous function, we get the first paragraph on the page with “paras[i]” … But we want to increment i by one for each iteration. This way, the next time the selection is called, it’ll be referring to the next element in the wrapped set. So, we must be sure to write paras[i++]. Then, it’s a simple matter of calling fadeout, and passing arguments.callee as the callback function, to allow for recursion. This will be equal to the function it’s contained in; so we’re essentially saying “rinse and repeat!”
XEROX CODE
alert(arguments.callee); // alerts the following
(function() {
$(paras[i++] || []).fadeOut('slow', arguments.callee);
})();
Note
If, for some reason, you’re using jQuery 1.3 or older, you need to specify what should happen when paras[i] is equal to an element that doesn’t exist. In older versions of jQuery, it returns an error, “undefined.” To compensate, we pass $(paras[i++] || []) to specify that, if the element doesn’t exist, we instead wrap an empty array, to avoid any errors.
It should be noted that, as of jQuery 1.4, this is unnecessary, as jQuery will return the jQuery object instead.
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web.










jQuery Lightbox Evolution only $12.00
Events Calendar Pro - Wordpr ... only $30.00 
Very nice Jeffrey
yh jeff, keep it up.
Nice tip!
Hadn’t seen that method before. Thanks!
Very cool. Great tip.
The i++ confused me for a moment, I thought you would need ++i, but now I understand. Very nice!
Nope – because ++i would first increment i. We want to get the first paragraph…and then increment i by one…preparing it for the next loop.
For those of you that (like me
) didnt really get the arguments.callee, this might be interesting for you, a little in depth explanation:
https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Functions_and_function_scope/arguments/callee#Example.3a_Using_arguments.callee_in_an_anonymous_recursive_function
Neat little trick Jeffrey!
Thanks, Kriesi. I’ll add a link to that page in the article above.
Very nice, Will be using it in the near future I suspect.
Great tip. I want to see little screencasts like this everyday
I love these quick tips, they’re the best part of Nettuts
Nicely done, very useful useful.
I only wish I knew this before
.
I wanted to ask, if the arguments.callee method works infinite in the background and consumes memory, what means that it calls the calling function as long as the user has the page open, or does ist stop the first time it doesn’t find a element in this case.
Nice tip, and i love quick tips!
I was wondering the same thing, anyone have any info on this?
Btw Jeff, thank you as always for sharing your knowledge.
No, it does not. Because the jQuery set, after there are no more elements that match the iterator, doesn’t contain any dom elements, nothing is passed to the fadeout method. Any if nothing is passed, the method doesn’t run.
Nice trick! Apparently, arguments.callee has been deprecated in ES5 – in strict mode it’ll throw an exception. More info: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ – this sucks quite a bit – and makes no sense to me.
You could always get the number of Paragraphs using jQuery .size or .length and make a while loop. Something like this:
var paras = $(‘p’),
i = 0;
// If using jQuery 1.4, you don’t need to do || [].
(function() {
// -1 is becouse it gets the number of paragraphs instead of their index number
while(i < (paras.size()-1)) {
$(paras[i++] || []).fadeOut('slow', arguments.callee);
}
})();
Offcourse i could be mistaken, since I havent used arguments.callee that much. But i'd like to hear more idea's since Begs got a good point there.
gr. dedego
You could always get the number of Paragraphs using jQuery .size or .length and make a while loop. Something like this:
while(i < (paras.size()-1))
Offcourse i could be mistaken, since I havent used arguments.callee before. But i’d like to hear more idea’s since Begs got a good point there.
gr. dedego
You could always get the number of Paragraphs using .size() or .length() and make a while loop (offcourse it isnt the same as an Index number, but it ‘could’ do the trick).
Offcourse i could be mistaken, since I havent used arguments.callee before. But i’d like to hear more idea’s since Begs got a good point there.
gr. dedego
Nice..
Thanks !
Nice Job, Jeffrey! Should come in handy and keep my code clean in the future…
What about this solution:
var i = 0;
$(‘p’).each( function(){
$(this).delay(i * 500).fadeOut(“slow”);
i++;
} );
@Jeffery You probably get asked this all the time, but what application do you use that lets you write keywords for snippets of code? Example: you typed in “html body” and all the code to start a basic HTML file appeared.
For Mac, check out TextExpander. For PC, see Texter.
Jeffrey, you have that response in TextExpander, don’t you
And in the outside chance that you’re using Linux, the default GNOME text editor (gedit) has a snippets plugin that allows the same functionality. Saves me a lot of time.
Nice, Thanks
That is a really neat magic show, I wonder what the practical application would be?
Jeff,
I just want to say thank you for all the hard work you do for Nettuts+ (and, of course, its audience
). It’s rare to find someone who has a passion for something like you do, and even more rare for that person to have the will and ability to share what they know. I have learned so much from watching your screencasts, and I am so grateful for the help you’ve been. Keep up the awesome work!
Thanks, Marshall!
I don’t really see how this method is any less cluttered than the first thb…
How it’s better than using callback functions? It’s much better because it can be more dynamic…not to mention that, in our example, you would need two nested functions to mimic the effect.
awesome, i prefer to use MoTools but i want to learn some JQuery a i really appreciate this TUT
Love it, great demo.
congrats you have written unreadable code
Nobody said it was perfect. But it might be your best option. Have a better idea?
How on earth is it unreadable? … If you know JavaScript and have a decent understanding of jQuery’s API then it couldn’t be simpler. What level of understanding should we have to accommodate when considering readability, hmmm?
Do you have a better idea than that? Even me as a beginner does understand how things work and I think Jeffrey did it very well.
Very nice tut!
Looks really interesting, but I wonder if there is a way to mix and mash elements?
Like what if I wanted the first 3 p elements to disappear and then 2 divs to slide from the left and then 1 p element turn red?
thank. tutorial very useful
Great tutorial thanks a lot!
However, there is one thing. After replicating the effect with some other jquery animations like slideUp, I went to make the effect trigggerable from a click event. I didn’t change any code from what you provided but the end result was that only 1 animation happened instead of all 3. Any thoughts on that? I can post code if you need it. Thanks!
Nice tutorial and actually taught me something today!
I just had to tweet this because I know it will help many people as much as it helped me get started with this stuff! jQuery ROCKS!!