You may not know this, but whenever you use jQuery commands like fadeIn, slideDown, and delay, you are implicitly making use of a jQuery queue behind the scenes. That queue is named fx, and it is the default queue that all animations use unless otherwise specified.

In this article, we will look at how jQuery animation queues work, how to create and manipulate them, and how to use them in a meaningful way.

Queue fundamentals

Each element has its own set of queues. For example, if we execute this code:

$("#foo").fadeOut();
$("#bar").fadeOut();

The elements #foo and #bar will fade out more or less simultaneously. This is because they have their own fx queues. However, if we execute the code:

$("#foo").fadeOut();
$("#foo").fadeIn();

The element #foo will fade out and then fade in, instead of getting stuck in some sort of tug of war for opacity. This is because they are both using the fx queue of #foo, and thus run one after another.

Creating and manipulating queues

jQuery provides 5 commands for interacting with queues, which are summarized in the table below.

Command Summary
animate Perform a custom animation of a set of CSS properties.
queue Show the queue of functions to be executed on the matched elements, or manipulate the queue of functions to be executed on the matched elements.
dequeue Execute the next function on the queue for the matched elements.
clearQueue Remove from the queue all items that have not yet been run.
delay Set a timer to delay execution of subsequent items in the queue.

So how do we create a queue? We simply use a queue command that takes a queueName argument. For example, we can use the queue command and add a function to queue. Let's try it first with the regular fx queue.

$("#foo").queue(function(next) {
    alert("I was queued!");
    next();
});

When this code is run on a page with a #foo element, it immediately emits an alert saying "I was queued!". This is because the fx queue will dequeue elements right after they're added. We can verify that the fx queue is being used by queuing an animation before our alert.

$("#foo").fadeOut().queue(function(next) {
    alert("I was queued!");
    next();
});

When this code is run the #foo element fades out and then an alert is shown. Now let's try it with a custom queue.

$("#foo").queue("custom", function(next) {
    alert("I was queued!");
    next();
});

Nothing happens. Why? Because unlike the default fx queue, custom queues are not dequeued immediately. They require an explicit dequeue call to get them started.

$("#foo").queue("custom", function(next) {
    alert("I was queued!");
    next();
})
.dequeue("custom");

What's the point?

At this point you may be wondering, what's the point? Why would I ever need to use queues? The answer is: to implement animation time-lines. Imagine you're making a game and you want to have an object float up wards for 2000 milliseconds. Furthermore, you would like said object to stay completely opaque for 1000 milliseconds before slowly becoming completely transparent over the remaining 1000 milliseconds. This time-line is shown below in tabular form (assuming that the object starts at top: 100px).

Time Top Opacity
0 100px 1.0
500 90px 1.0
1000 80px 1.0
1500 70px 0.5
2000 60px 0.0

At first glance, it appears that the animate command could take care of this:

$("#object").animate({opacity: 0, top: "-=40"}, {duration: 2000});

Unfortunately, this code will fade the object out over 2000 ms, instead of waiting 1000 ms then fading out over the remaining 1000 ms. delay can't help either, because it would delay the upward floating as well. At this point we can either fiddle with timeouts or, you guessed it, use queues.

$("#object")
.delay(1000, "fader")
.queue("fader", function(next) {
    $(this).animate({opacity: 0}, 
        {duration: 1000, queue: false});
    next();
})
.dequeue("fader")
.animate({top: "-=40"}, {duration: 2000})

In this example, we have two queues: the fx queue and the fader queue. First off, we setup the fader queue. Since we want to wait 1000 ms before fading, we use the delay command with 1000 ms (line 2). Next, we queue up an animation that fades the object out over 1000 ms (line 3-7). Pay close attention to the queue: false option (line 5) we set in the animate command. This is critical, as it ensures that the animate doesn't use the fx queue. Finally, we unleash the queue using dequeue and immediately follow it with a regular fx-using animate call to move the top of the object up 40 pixels (line 9).

Conclusion

jQuery makes use of implicit animation queues behind the scenes whenever you run an animation. By taking advantage of jQuery queue commands, custom animation queues can be constructed that enable certain complex animation stuctures, like time-lines, that would be otherwise impossible without using intervals or timeouts.