官方文档:
队列的本质是一个数组,对队列的理解先从数组的push和shift开始。
push是从数组尾端插入新的元素,shift是从数组首端删除元素;分别对应队列中得queue和dequeue。我们知道jquery所有动画基于animate方法,而animate的动画默认保存在名为fx的动画队列中。
queue就是将动画放进队列中,dequeue就是将动画从队列中删除并执行它。
$.fn.queue传参形式有:
- queue([queue_name]) 查看队列,传入队列名2. queue([queue_name], new_queue) 添加new_queue到队列中,对列名默认为fx,new_queue类型为数组3. queue([queue_name], callback) 添加callback回调函数到队列中,对列名默认为fx,callback类型为函数,当该函数被调用时,会从弹出队列中的下一个元素。
一、队列的存在和执行
我们在页面中常使用这样的语句:
$('#foo').slideUp().fadeIn();
它的执行顺序是元素先slideUp后再fadeIn,slideUp和fadeIn有先后顺序。jquery会默认地将它们放进名为fx的队列中,我们可以这样认为:
var fx = [slideUp, fadeIn];
//相当于
$('#foo').queue('fx', fx);
//第一步:出列第一个元素slideUp并执行它
$('#foo').dequeue('fx'); //fx = ['inprogress', fadeIn]
//第二步:出列第二个元素fadeIn并执行它
$('#foo').dequeue('fx'); //fx = ['inprogress']
//第三步,队列fx为空,动画执行完毕
fx = [];
通过不断的dequeue,fx每个元素逐个依次出列执行,直至队列没有元素。
所以我们很容易发现,当我们书写下面这个语句的时候,执行顺序并不是按照书写顺序来执行了:
$('#foo').slideUp().fadeIn().css({'width':'200px'});
它的执行顺序是元素宽度马上变成200px的同时,slideUp也在执行,slideUp执行完后再执行fadeIn。
二、队列的回调
官网中的例子:
$(document.body).click(function () {
$("div")
.show("slow")
.animate({left : "+=200"}, 2000)
.queue(function () {
$(this).addClass("newcolor").dequeue();
})
.animate({left : "-=200"}, 500)
.queue(function () {
$(this).removeClass("newcolor").dequeue();
})
.slideUp();
});
在click之后,div元素会先出现,再往右运动两秒,接着添加newcolor的类名,再往左回到起点,去除newcolor类名后收起来消失。
.queue(function () {
$(this).addClass("newcolor").dequeue();
})
这个匿名函数是queue的回调函数,$(this).dequeue()在这里的作用是弹出队列中的下一个元素。
如果我们将这句话中的dequeue去除会怎样呢?
$(document.body).click(function () {
$("div")
.show("slow")
.animate({left : "+=200"}, 2000)
.queue(function () {
$(this).addClass("newcolor");//.dequeue();
})
.animate({left : "-=200"}, 500)
.queue(function () {
$(this).removeClass("newcolor").dequeue();
})
.slideUp();
});
运行后可以知道脚本在执行完addClass(’newcolor’)后停止了。虽然队列中还有元素在排队,但是去除dequeue后没有将下个元素抛出,所以停止了执行。这就是dequeue的作用,弹出下一个元素,让队列执行下去。
如果将上面的脚本再修改下:
$(document.body).click(function () {
$("div")
.show("slow")
.animate({left : "+=200"}, 2000)
.queue(function () {
$(this).addClass("newcolor").dequeue();
$(this).slideDown("slow");//添加slideDown
})
.animate({left : "-=200"}, 500).queue(function () {
$(this).removeClass("newcolor").dequeue();
})
.slideUp();
});
div中的fx队列最后会增加一个排队元素slideDown,所以最后slideUp收起收,又再缓缓地slideDown下来。
三、队列的自定义
我们可以通过这样的方式来创建自己的队列:
var queue = [
function () {
console.log('NO.1');
},
function () {
console.log('NO.2');
}
];
$('div').queue('a1', queue);
这样我们创建了一个名为a1的队列,队列里有两个元素在排队。
打印队列长度:
$('div').queue('a1').length;//输出2
通过dequeue来让队列的第一个元素出列:
$('div’).dequeue('a1’);//输出NO.1
打印下队列现在的长度:
$('div’).queue(‘a1').length;//输出1
接着再dequeue一次,queue队列就会清空,全部队列出列执行完毕。
按照这个思路,我们可以运用之前学习的回调函数方法,将出列的方法放在回调函数中,在完成一个动画后调用出列,就可以将队列依次执行。
思路:
var queue = [
function () {
$('item-1').fadeIn(function(){
$('div').dequeue('a1');
});
},
function () {
$('item-2').fadeIn(function(){
$('div').dequeue('a1');
});
},
function () {
$('item-3').fadeIn(function(){
$('div').dequeue('a1');
});
}
];
$('div').queue('a1', queue);
//触发动画
$('div').dequeue('a1');
成型:
var queue = [
function () {
$('item-1').fadeIn(dequeue);
},
function () {
$('item-2').fadeIn(dequeue);
},
function () {
$('item-3').fadeIn(dequeue);
}
];
var dequeue = function(){
$('div').dequeue('a1');
};
$('div').queue('a1', queue);
//触发动画
dequeue();
item-1,item-2,item-3会依次的出现。
四、队列的运用场景
在动画效果中需要按序来执行的时候都可以用到队列,特别是在动画绑定在不同的dom元素上和某些效果没有用到animate方法的时候。
案例:
- 京东双12头部文案出现顺序:http://sale.jd.com/act/J067lGoWuw.html
五、作业