The .animate() method,
as we've just discovered, is very useful for creating simultaneous
effects in a particular set of elements. There may be times, however,
when we want to queue our effects, having them occur one after the other.
Working with a single set of elements
When applying multiple effects to the same set of elements, queuing is easily achieved by chaining those effects. To demonstrate this queuing, we'll again move the Text Size
box to the right, increase its height and increase its border width.
This time, however, we perform the three effects sequentially, simply by
placing each in its own .animate() method and chaining the three together:
$(document).ready(function() {
$('div.label').click(function() {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.animate({left: paraWidth - switcherWidth},
'slow')
.animate({height: '+=20px'}, 'slow')
.animate({borderWidth: '5px'}, 'slow');
});
});
Recall that chaining permits us to keep all three .animate() methods on the same line, but here we have indented them and put each on its own line for greater readability.
We can queue any of the jQuery effect methods, not just .animate(), by chaining them. We can, for example, queue effects on<div id="switcher"> in the following order:
1. Fade its opacity to .5 with .fadeTo().
2. Move it to the right with .animate().
3. Fade it back in to full opacity with .fadeTo().
4. Hide it with .slideUp().
5. Show it once more with .slideDown().
All we need to do is chain the effects in the same order in our code:
$(document).ready(function() {
$('div.label').click(function() {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.fadeTo('fast',0.5)
.animate({
'left': paraWidth - switcherWidth
}, 'slow')
.fadeTo('slow',1.0)
.slideUp('slow')
.slideDown('slow');
});
});
But what if we want to move the<div>
to the right at the same time as it fades to half opacity? If the two
animations were occurring at the same speed, we could simply combine
them into a single .animate() method. But in this example, the fade is using the'fast' speed while the move to the right is using the'slow' speed. Here is where the second form of the .animate() method comes in handy:
$(document).ready(function() {
$('div.label').click(function() {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.fadeTo('fast',0.5)
.animate({
'left': paraWidth - switcherWidth
}, {duration: 'slow', queue: false})
.fadeTo('slow',1.0)
.slideUp('slow')
.slideDown('slow');
});
});
The second argument, an options map, provides the queue option, which when set to false makes the animation start simultaneously with the previous one.
One final observation about
queuing effects on a single set of elements is that queuing does not
automatically apply to other, non-effect methods such as .css(). So let's suppose we wanted to change the background color of<div id="switcher"> to red after the .slideUp() but before the slideDown(). We could try doing it like this:
$(document).ready(function() {
$('div.label').click(function() {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.fadeTo('fast',0.5)
.animate({
'left': paraWidth - switcherWidth
}, 'slow')
.fadeTo('slow',1.0)
.slideUp('slow')
.css('backgroundColor','#f00')
.slideDown('slow');
});
});
However, even though the
background-changing code is placed at the correct position in the chain,
it occurs immediately upon the click.
One way we can add non-effect methods to the queue is to use the appropriately named .queue() method. Here is what it would look like in our example:
$(document).ready(function() {
effectsnon-effect methods, adding$('div.label').click(function() {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.fadeTo('fast',0.5)
.animate({
'left': paraWidth - switcherWidth
}, 'slow')
.fadeTo('slow',1.0)
.slideUp('slow')
.queue(function() {
$switcher
.css('backgroundColor', '#f00')
.dequeue();
})
.slideDown('slow');
});
});
When given a callback function, as it is here, the .queue()
method adds the function to the queue of effects for the matched
elements. Within the function, we set the background color to red and
then add the corollary .dequeue() method. Including this .dequeue() method allows the animation queue to pick up where it left off and complete the chain with the following .slideDown('slow') line. If we hadn't used .dequeue(), the animation would have stopped.
We'll discover another way to queue non-effect methods as we examine effects with multiple sets of elements.