jQuery动画高级用法(下)――详解animation中的.queue()函数2011-09-19 20:00自定义队列
我之前有提过其实可以不使用它默认的'fx'队列,这节就教大家怎么自定义一个属于自己的队列,很简单:
我想建立一个名为'custom'的队列,里面有一个能使黑色小方块改变背景颜色的方法,如下:
$("div").queue("custom", function(next) {
$('div').css({'background':'red'});
next();
});
所见即所得――前面一个'custom'代表新队列的队列名(要是我也取'fx'会怎么样?我也不知道,有兴趣的朋友尝试之后可以留言告诉我结果,我也有兴趣会知道),后面仍然是回调函数,把你想执行的功能堆砌进去。
但就这段代码而已,待你真正添加进网页,并且尝试运行,会发现并非“所见即所得”,压根就不会有任何效果。因为我故意省略了一段最最关键的语句……修改后的如下:
$("div").queue("custom", function(next) {
$('div').css({'background':'red'});
next();
})
.dequeue("custom"); //this is the key
对,就是这句,.dequeue("custom")。一般对与dequeue()的定义是“删除队列中最顶部的函数,并且执行它”。我并不赞同用“删除”这个字眼,而是倾向于“取出”,其实这个函数的功能就好像是一个数据结构中队列的指针,待队列中前一个函数执行完后,取下一个队列最顶端的函数。
实战
OK,主要的几个知识点都介绍完了。或许你会问,我们真的会用到这么复杂的动画操作吗呢?我相信大多数人士不会的,动画在网页中只是小小的点缀,但是小心驶得万年船。在这里我就照搬Cameron Mckay博客上的关于队列应用的例子
假设你要这么一个效果:让一个物体向上浮动2000毫秒(2秒),并且在前1000毫秒物体完全不透明,而在后1000毫秒物体从完全不透明变成完全透明,为了解释的更清楚,给出了下面的这个时间轴表(假设物体开始在距容器顶部100px的位置,也就是top:100px;):
时间(毫秒) 距顶端高度 不透明度
0 100px 1.0
500 90px 1.0
1000 80px 1.0
1500 70px 0.5
2000 60px 0.0
从时间轴表中我们可以更清晰的看到我们想要的效果,在这2000毫秒的时间内,物体的高度一致在均匀变化,逐渐减小,而不透明度在前1000毫秒始终保持为1.0,而在后1000毫秒才逐渐减小直至完全为0。
如果我们暂且只考虑向上浮动和透明效果,我们可能会写出这样的语句:
$("#object").animate({opacity: 0, top: "-=40"}, {duration: 2000});
很遗憾,这样的语句只能让物体在整体2000毫秒中都处于逐渐向不透明转化的过程,也就是不能让它在前1000毫秒中保持100%不透明――于是我们用queue来解决这个问题:
$("#object")
.delay(1000, "fader")
.queue("fader", function(next) {
$(this).animate({opacity: 0},
{duration: 1000, queue: false});
next();
})
.dequeue("fader")
.animate({top: "-=40"}, {duration: 2000})
我们先来看它的思路:把控制不透明度和控向上移动的动画分别存储在两个队列中,控制向上移动的队列按默认情况进行(在2000毫秒内完成),而不透明度的控制在1000毫秒内执行,但这个队列要晚于默认队列1000毫秒执行
再简单一点,就是:前1000毫秒,只有控制高度的“fx”队列执行,而后1000毫秒,控制不透明度的“fader”队列和控制高度的“fx”并行
首先准备两个队列,
一个是默认的"fx",存储高度变化动画:
.animate({top: "-=40"}, {duration: 2000})
用来另一个是自定义的"fader"的队列,来存储不透明度变化的动画:
.animate({opacity: 0}, {duration: 1000, queue: false});
注意上面这段代码中的"queue:false",这是很关键的一句话,目的是让这个animate不进入默认的"fx"队列中
任何的动画效果都会进入"fx"队列中,即使你定义在.queue()中的动画也是一样,并且动画效果,务必会按顺序执行,比如说下面这段代码:
$('#object').slideUp(1000) .slideDown(1000) .animate({width: '50px'}, {duration: 1000});
运行后它只会按照顺序来执行,先收起,再放下,再把宽度收缩为50px
但是一旦我加入了"queue:false"这个参数:
$('#section3a').slideUp(1000)
.slideDown(1000)
.animate({width: '50px'}, {duration: 1000, queue: false});
你会发现在收缩放下的同时,object的宽度也在收缩
本来线性执行的slideUp,slideDown,animate,变成了animate和slideUp,slideDown并行:
运行结果如下
本例完整代码:
function queuetrue(){
$('#section3a').slideUp(1000)
.slideDown(1000)
.animate({width: '50px'}, {duration: 1000});
}
function queuefalse(){
$('#section3a').slideUp(1000)
.slideDown(1000)
.animate({width: '50px'}, {duration: 1000, queue: false});
}
$("#section3a-input").click(function(){
$("#section3a").css({'width':'100px'});
queuetrue();
});
$("#section3b-input").click(function(){
$("#section3a").css({'width':'100px'});
queuefalse();
});
OK,我们回过头来再看实战中的这个例子:
$("#object")
.delay(1000, "fader")
.queue("fader", function(next) {
$(this).animate({opacity: 0},
{duration: 1000, queue: false});
next();
})
.dequeue("fader")
.animate({top: "-=40"}, {duration: 2000})
其实前三个语句(这里所说的语句以"."为区分标志),做了这么几件事:
定义一个名为fader的队列,专用于控制不透明度的改变――.queue()语句
让它1000毫秒后执行――.delay()延时函数,延时fader队列的执行时间;.dequeue执行fader队列。