How to use custom jQuery animation queues
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.
8 comments