views:

107

answers:

3

I'm trying to combine matching something like:

$(".item").each(function(i) {
    //animation here
});

with jQuery's inherent chaining functionality that forces the animation to wait until the previous animation has completed, e.g.:

$(".item").each(function(i) {
    $(this).animate({marginLeft:"0"}, 60);
});

And then trigger a .load function after the animations have completed. (Basically, I want to fade four items out in order [one after the next, not all at once], then load four new items into the same div, replacing the first four).

Any ideas how I can do this in a reusable/variable way?

Thanks!

+1  A: 

How about checking if the element is the last one and then adding a callback?

$(".item").each(function(i, elem) {
    var callback = $(elem).is(':last') ? function() {
        //dosomething
    } : function(){};
    $(this).animate({marginLeft:"0"}, {duration: 60, complete: callback);
});
David
Thanks! Just had to tweak syntax on the duration/callback part.
Tegeril
Hmm, this doesn't seem to be working. Going to play with it a bit but if you can refine, that'd be great.
Tegeril
+1  A: 

Just specify a callback for the animations and track how many items have been faded out. Then, when they're all done, remove them and add the new ones.

var items = $('.item');
var parent = items.parent();
var itemCount = items.length;
items.each(function()
{
    $(this).fadeOut('medium', function()
    {
        itemCount--;
        if (itemCount == 0)
        {
            // Remove the items and add the new ones.
            items.remove();
            parent.append('...')
        }
    });
});
Will Vousden
Actually, David's is better!
Will Vousden
Thanks for the help - upvoted, but ultimately marked David's.
Tegeril
Ok, finally getting a chance to read though these. Neither of these is accomplishing the task. jQuery's animation chaining sets up animations such that one must complete before the next begins. That's what I'm looking for :\
Tegeril
So you want to fade them out one by one, then add them one by one?
Will Vousden
Yes, I have appended a solution I wrote that gets the job done.
Tegeril
A: 
$("#more:not(.disabled)").live("click", function(event) {
    event.preventDefault();

    var urlPieces = (event.target.href).split("/");
    var nextURL = urlPieces[urlPieces.length - 2] + "/" + urlPieces[urlPieces.length - 1];
    var items = $(".item");
    var itemCount = items.length;   

    items.each(function(i) {
        var passthru = this;
        window.setTimeout(function() {
            $(passthru).animate({opacity:"0"}, 60, function() {
                if (i == itemCount - 1) {
                    $("#browse").load(nextURL + " .item, #controls", fadeInNew);
                }
            });
        }, 60*i);
    });
});

fadeInNew handles the new one by one fade in elsewhere, but this was what I was looking for more or less with a bit of extra code around it to maybe shed some light on what was happening (there's a next arrow with a url in its href, if javascript is on, I need the URL of the next page relative to the current, if it's off, it follows that url as an href and loads a new page which has the same content on the page except for the new items that would have been $.load-ed.

Tegeril