views:

62

answers:

2

I am trying to make a sequential animation, where a loop iterates through a list of elements .post's and fades them in slow. The difficult part is having it so that the next iteration begins fading in before the last one has finished fading. All I have so far is a simple sequential animator that fades them in one after the other.

$(".post").hide();
var posts = $(".post"),
    i = 0;
(function() {
  $(posts[i++]).fadeIn('slow', arguments.callee);
})();

Does anyone know how I could change this to allow .post to fadeIn() before the previous elem/s have finished?

+4  A: 

Iterate over them using each() and use a setTimeout() for each one, multiplying the duration of the animation by the current index in the each.

var posts = $(".post").hide();

  // Holds reference to the index of the current iteration
  // ------------------v
posts.each(function( index ) {
    var $th = $(this);
    setTimeout(function() {
        $th.fadeIn('slow');   // Removed arguments.callee
    }, index * 300);
});

So each setTimeout() will have a duration of n*600, which should give you the effect you want.

By the way, if you don't need the posts variable for any other purpose, you can eliminate it and chain the .each() after the .hide(), as in $(".post").hide().each(func...)


EDIT: I had an error. I was using this inside the setTimeout() which has a different value. Edited to pass in the correct value.

EDIT: Mis-read the question. Changed the duration of setTimeout() to 300 to give a partial overlap in the animations.

patrick dw
Excuse my daftness. I'm not exceptional with jquery. But this returns 'too much recursion'. And I'm not quite sure even where to begin deciphering how
Trip
@Trip - Not sure why you would get that, but see my update. I had an error in the code.
patrick dw
@Trip - Also, make sure you're not already in a loop, if there's more code than is shown in your question. And I'm not sure what the purpose of `arguments.callee` is. You may want to remove that.
patrick dw
Awesome, it works, i was just dumb ( as usual ). For it to be obvious, I changed the fadeIn(1500), and the index * 300
Trip
@Trip - Here's an example that shows it in action. http://jsfiddle.net/rbyN6/ I would need to see more of your code to see what is wrong. And I'm not sure what you mean by *"before the last one is finished"*. I thought you wanted them to be sequential. Are you saying you want them to be simultaneous? Or partially overlapping?
patrick dw
@Trip - Ok, I see. You wanted the partial overlap. Yep, changing the duration would do it. :o)
patrick dw
+1  A: 

Similar to patrick's solution, but a little cleaner in my opinion

(function() {
  $(".post").hide().each(function(index){
    $(this).delay(index * 300).fadeIn('slow');
  });
})();

demo, the 300 is the duration of the delay where as the 'slow' is the duration of the fade

Ah, but that is no different then the one I already had.
Trip
huh? what do you mean?
Ah yes, it does work, I realized that after changing the params to make it a more obvious tween.
Trip