章节
问答
课签
笔记
评论
占位
占位

queue与dequeue

$.queue : 显示或操作匹配的元素上已经执行的函数列队
这个方法有两个作用,它既是 setter,又是 getter。第一个参数 elem 是 DOM 元素,第二个参数 type 是字符串,第三个参数 data 可以是 function 或数组。
var body = $('body');
function cb1() {alert(1)}
function cb2() {alert(2)}

//set,第三个参数是函数
$.queue(body, 'aa', cb1); 
$.queue(body, 'aa', cb2); 

//get
$.queue(body, 'aa')  //[function ,function]
这个方法有点类型 get 有点类似队列的 push 操作,jQuery 的方法的接口重载是非常严重的,经常同一个接口即是 set 也是 get,不管符不符合基本原则,但是它却很实用。无非就是把数据给缓存起来,为什么载体是一个jQuery对象,因为保存数据的手段是通过data数据缓存实现的。
queue: function(elem, type, data) {
   //参考右边实现
}
data 与 jQuery 对象之间是通过 uuid 建立了一个无耦合的映射关系,具体可以翻阅之前的关于“数据缓存”,源码有一个默认处理 type = (type || "fx") + "queue" 可见是专职供fx动画队列处理的。

$.dequeue : 匹配的元素上执行队列中的下一个函数
var body = $('body');
function cb1() {console.log(11111)}
function cb2() {console.log(22222)}
//set
$.queue(body, 'aa', cb1); // 第三个参数为function
$.queue(body, 'aa', cb2);

$.dequeue(body, 'aa')  //11
$.dequeue(body, 'aa')  //22
出列就有点类似 shift 的操作,但是不同的是还会执行这个 cb1 与 cb2,将回调函数出列执行,每调用一次仅出列一个,因此当回调有 N 个时,需要调用 $.dequeue 方法 N 次元素才全部出列,来看看源码:
var dequeue = jQuery.queue(elem, type),
  //参考右边实现
};
知道原理了, 这个就很简单了,通过 queue 的 get 取出队列的所有数据,判断一下长度,然后截取出第一个,然后做好一个预处理生成下一个的 next。
 
这里有一个hooks?

仔细分析下这个内部 queueHooks
_queueHooks: function(elem, type) {
    var key = type + "queueHooks";
    return data_priv.get(elem, key) || data_priv.access(elem, key, {
        empty: jQuery.Callbacks("once memory").add(function() {
            data_priv.remove(elem, [type + "queue", key]);
        })
    });
}
我们说了dequeue不仅是取出来还需要执行,在执行的时候把next与hooks传递给外部的回调,这就是js的逻辑上的很绕的地方,在内部可以传递一个引用出去,又能提供外部调用或者执行。
fn.call(elem, next, hooks)
因为传递了next,所以我们的代码可以参考右边代码,next内部仍然调用$.dequeue,这样可以接着执行队列中的下一个 callback,$.dequeue 里的 hooks 是当队列里所有的 callback 都执行完后(此时 startLength 为0)进行最后的一个清理工作。
if ( !startLength && hooks ) {
    hooks.empty.fire();
}
钩子其实就是 jQuery.Callbacks 对象,可以实现一个收集器的功能,至于在什么情况下时候,之后动画中开始分析,所以队列的本质是利用 Array 的 push 和 shift 来完成先进先出(First In First Out),但是这个方法的缺点也很明显,无法单独做一个独立的模块处理,因为它必须要跟 jQuery 对象吻合,而且对传递的数据只能是函数。

任务

?不会了怎么办
||

提问题

写笔记

截图
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最新 点赞
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?