March 5, 2010

Using jQuery's queue(), dequeue() and delay() Methods

These methods were very confusing to me so I decided to do some demystification and see what the hell was going on. jQuery's documentation sets them up as methods related to the effects api. By default this is true, but I found this little misleading.

queue() / dequeue(), in short, allows you to create a queue of functions to be executed on the matched element(s) and then execute them in order.

delay() allows you to create a delay between functions in the queue.

None of the functions are run until the dequeue() method is run. This could be a click event, for instance.

Take for instance the following code:

$(document).ready(function () {
  // cache the body element
  var body = $('body');

  /*
      Create a "bodyQueue" queue for the body element and add a function into it. After this function runs it will delay the "bodyQueue" queue by 5 seconds. None of the functions are run until an event triggers the dequeue() method. This event is defined at the end using a click on the body.
    */
  body
    .queue('bodyQueue', function () {
      console.log('1st function. Next one is delayed by 5 seconds');
      $(this).dequeue('bodyQueue');
    })
    .delay(5000, 'bodyQueue');

  // Add another
  body.queue('bodyQueue', function () {
    console.log('2nd function (delayed 5 seconds)');
    $(this).dequeue('bodyQueue');
  });

  // Add another
  body.queue('bodyQueue', function () {
    console.log('3rd function');
    $(this).dequeue('bodyQueue');
  });

  // Add another
  body.queue('bodyQueue', function () {
    console.log('4th function');
    $(this).dequeue('bodyQueue');
  });

  // Add another and delay the "bodyQueue" queue by 5 seconds.
  body
    .queue('bodyQueue', function () {
      console.log('5th function. Next one is delayed by 5 seconds');
      $(this).dequeue('bodyQueue');
    })
    .delay(5000, 'bodyQueue');

  // Add the last one
  body.queue('bodyQueue', function () {
    console.log('6th function (delayed 5 seconds)');
  });

  // Show the queued functions when the page loads
  var queue = body.queue('bodyQueue');

  console.log(
    'There are ' + queue.length + ' functions left in the "bodyQueue" queue:'
  );

  console.log(body.queue('bodyQueue'));

  // Add an event to fire the "bodyQueue" queue
  body.click(function () {
    // Run everything in the "bodyQueue" queue
    body.dequeue('bodyQueue');
  });
});

What I've defined here is a queue with the name bodyQueue, attached it to the body element and added a series of functions. When the body element registers a click event, the callback runs body.dequeue('bodyQueue'), firing the queued functions in bodyQueue.

Resources:

jQuery for Designers | API: queue & dequeue

jQuery in Action 2nd edition: Queuing functions for execution