Sequentially chain your callbacks in jQuery - Three ways
August 22nd, 2008
I had a challenge to get four divs to fade in sequentially.
Writing this out the long way is not really my favorite:
$("#vehicle1").fadeIn("slow", function(){ $("#vehicle2").fadeIn("slow", function(){ $("#vehicle3").fadeIn("slow", function(){ $("#vehicle4").fadeIn("slow"); }); }); });
Ewwww. right?
After some conversation in the #jQuery IRC channel, I present twothree classier ways of accomplishing the same thing:
Self-executing callback chaining
(function showVehicle(elem){ elem.fadeIn('slow',function(){ $(this).next().length && showVehicle($(this).next()); }); })( $("div.vehicle:first") );
Custom event triggering (via: ajpiano)
$('div.vehicle') .bind('showVehicle',function(e) {$(this).fadeIn('slow',function(){ $(this).next().length && $(this).next().trigger("showVehicle"); })}) .eq(0) .trigger('showVehicle');
Update 2009.06.15: I'm incredibly impressed with temp01's solution in the comments. So that's my recommendation going forward:
Self-executing callback chain on an arbitrary jQuery object (via: temp01)
(function hidenext(jq){ jq.eq(0).fadeOut("fast", function(){ (jq=jq.slice(1)).length && hidenext(jq); }); })($('div#bodyContent a'))
Follow me on twitter: @paul_irish
I won't have you diss my way of doing it on IRC ;)
Here it another way of doing a recursive call with jQuery:
It might not be all that pretty and jQuery-like, but it still works.. :)
Another way - works on any jquery object(not just on sibling elements):
@temp01 That is very very nice, temp01. As far as flexibility is concerned, I think that's the nicest implementation here.
@Paul Irish
I'm trying to develop a similar effect of the ted.com site where elements load sequentially over time. Can this solution work for that with times (500, 1000, 1200) instead of range settings (slow, medium, fast)?
@Trey Yah totally. Just replace the 'fast' shorthand with a millisecond value.
You could also do something like:
for some randomness.
i have just achieved the effect by a simple computer science 101 recursive function:
another prettier way to do it, rather than waiting for the callback to fire, is to start each element fading up at a certain increment, say 200ms apart each, but have each element take longer than the triggering increment to complete its fade up. this is a prettier look.
@temp01
really neat huh?
Here is one that I've been using. It fades in items sequentially then after a brief pause slowly fades them out again.
This one comes from NetTuts (http://tinyurl.com/ycm4bap), slightly modified to use a named function instead of arguments.callee (depricated):