Entries Tagged 'jquery' ↓

Sequentially chain your callbacks in jQuery - Two ways

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 two 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');

jQuery doOnce plugin for chaining addicts

// jQuery doOnce plugin
jQuery.fn.doOnce = function(func){ 
    func.apply(this); 
    return this; 
}

This allows you to execute arbitrary script during a single chain. A bad example of alert() debugging follows:

// example usage of doOnce()
$('div.toGrow')
  .doOnce(function(){
    alert('before color swap');
  })
  .css({ backgroundColor: 'red'})
  .find('h2')
    .text('And now we\'re red')
    .end() // go back to the div.toGrow
  .animate({ height: '+=50px'},'normal','swing',function(){
    $(this)  // callback when animations complete
      .find('h2')
        .text('And now we\'re taller')
        .doOnce(function(){
          alert('animation done');
        });
  });

Note this is a little different than each(), which will execute once for every element in your current collection.
The code is pretty trivial, but sometimes you just feel like it. Nobody likes to break the chain!