4.5 并发与排队效果 4.5.1 处理一组元素

4.5 并发与排队效果

通过刚才的例子,可以看出.animate()方法在为一组特定的元素创建并发效果时非常有用。然而,有的时候我们需要的则是排队效果,即让效果一个接一个地发生。

4.5.1 处理一组元素

当为同一组元素应用多重效果时,可以通过连缀这些效果轻易地实现排队。为了示范排队效果,我们仍以代码清单4-17为例,移动Text Size盒子、增加其高度、加宽其边框。不过,这次我们相继地执行这三个效果——很简单,只要把它们分别放在.animate()方法中并连缀起来即可,参见代码清单4-18。

1
2
3
4
5
6
7
8
9
10
11
12
$(document).ready(function() { 
$('div.label').click(function() {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.css({position: 'relative'})
.animate({left: paraWidth - switcherWidth}, 'slow')
.animate({height: '+=20px'}, 'slow')
.animate({borderWidth: '5px'}, 'slow');
});
});

虽然连缀允许我们把这两个.animate()方法放在同一行,但为了更好的可读性,这里故意将它们分开放在了各自的一行中。
通过使用连缀,可以对其他任何jQuery效果进行排队,而并不限于.animate()方法。比如说,我们可以按照下列顺序对<div id="switcher">上的效果进行排队。
(1) 通过.fadeTo()将其不透明度减退为0.5。
(2) 通过.animate()将其移动到右侧。
(3) 通过.fadeTo()将其渐增回完全不透明。
(4) 通过.slideUp()隐藏它。
(5) 通过.slideDown()再将其显示出来。
我们所要做的,就是在代码中按照相同的顺序连缀这些效果,如代码清单4-19所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(document).ready(function () {
$('div.label').click(function () {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.css({ position: 'relative' })
.fadeTo('fast', 0.5)
.animate({ left: paraWidth - switcherWidth }, 'slow')
.fadeTo('slow', 1.0)
.slideUp('slow')
.slideDown('slow');
});
});

1. 越过队列

不过,要是想在这个<div>不透明度减退至一半的同时,把它移动到右侧应该怎么办呢?如果两个动画以相同速度执行,则可以简单地把它们组合到一个.animate()方法中。但这个例子中的.fadeTo()使用的速度字符串是’fast',而向右移动的动画使用的速度字符串是’slow'。在这种情况下,第二种形式的.animate()方法又可以派上用场了,参见代码清单4-20。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(document).ready(function() { 
$('div.label').click(function() {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.css({position: 'relative'})
.fadeTo('fast', 0.5)
.animate({
left: paraWidth - switcherWidth
}, {
duration: 'slow',
queue: false
})
.fadeTo('slow', 1.0)
.slideUp('slow')
.slideDown('slow');
});
});

第二个参数(即选项对象)包含了queue选项,把该选项设置为false即可让当前动画与前一个动画同时开始。

2. 手工队列

有关为一组元素应用排队效果的最后一个需要注意的问题,就是排队不能自动应用到其他的非效果方法,如.css()。下面,假设我们想在.slideUp()执行后但在.slideDown()执行前,把<div id="switcher">的背景颜色修改为红色,可以尝试像代码清单4-21这样来做。

然而,即使把修改背景颜色的代码放在连缀序列中正确的位置上,它也会在单击后立即执行。把非效果方法添加到队列中的一种方式,就是使用.queue()方法。代码清单4-22就是在这个例子中使用.queue()方法的代码片段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(document).ready(function () {
//其他代码...
$('div.label').click(function () {
var paraWidth = $('div.speech p').outerWidth();
var $switcher = $(this).parent();
var switcherWidth = $switcher.outerWidth();
$switcher
.css({ position: 'relative' })
.fadeTo('fast', 0.5)
.animate({
left: paraWidth - switcherWidth
}, {
duration: 'slow',
queue: false
})
.fadeTo('slow', 1.0)
.slideUp('slow')
.queue(function (next) {
$switcher.css({ backgroundColor: '#f00' });
next();
})
.slideDown('slow');
});
});

像这样传递一个回调函数,.queue()方法就可以把该函数添加到相应元素的效果队列中。在这个函数内部,我们把背景颜色设置为红色,然后又调用了next()方法,其返回的结果将作为参数传给回调函数。添加的这个next ()方法可以让队列在中断的地方再接续起来,然后再与后续的.slideDown('slow')连缀在一起。如果在此不使用next()方法,动画就会中断。
在下面讨论多组元素的效果之后,我们会介绍另一种向队列中添加非效果方法的方式。