Quick Tip: Easy Sequential Animations in jQuery
videos

Quick Tip: Easy Sequential Animations in jQuery

Share

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.

Related Posts

Add Comment

Discussion 44 Comments

  1. Emir says:

    Very nice Jeffrey

  2. Jason P says:

    Nice tip!

    Hadn’t seen that method before. Thanks!

  3. Jason says:

    Very cool. Great tip.

  4. The i++ confused me for a moment, I thought you would need ++i, but now I understand. Very nice!

  5. Kriesi says:

    For those of you that (like me :D ) 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! :)

  6. Very nice, Will be using it in the near future I suspect.

  7. Thierry says:

    Great tip. I want to see little screencasts like this everyday ;)

  8. lickynee says:

    I love these quick tips, they’re the best part of Nettuts

  9. Michal Kozak says:

    Nicely done, very useful useful.

    I only wish I knew this before :) .

  10. begs says:

    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!

    • Richard says:

      I was wondering the same thing, anyone have any info on this?

      Btw Jeff, thank you as always for sharing your knowledge.

      • Jeffrey Way says:

        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.

  11. 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.

  12. dedego says:

    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

  13. Dennis says:

    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

  14. Dennis says:

    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

  15. Danny says:

    Nice Job, Jeffrey! Should come in handy and keep my code clean in the future… :)

  16. Martin says:

    What about this solution:

    var i = 0;
    $(‘p’).each( function(){
    $(this).delay(i * 500).fadeOut(“slow”);
    i++;
    } );

  17. Dan says:

    @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.

  18. That is a really neat magic show, I wonder what the practical application would be?

  19. Marshall says:

    Jeff,

    I just want to say thank you for all the hard work you do for Nettuts+ (and, of course, its audience :-P ). 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!

  20. brett says:

    I don’t really see how this method is any less cluttered than the first thb…

    • Jeffrey Way says:

      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.

  21. xRommelx says:

    awesome, i prefer to use MoTools but i want to learn some JQuery a i really appreciate this TUT

  22. goran says:

    congrats you have written unreadable code

  23. w1sh says:

    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?

  24. thank. tutorial very useful

  25. Aidan Boyle says:

    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!

  26. e11world says:

    Nice tutorial and actually taught me something today!

  27. 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!!

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.