jQ的队列管理【前篇】
发布在# 菜鸟解读 jQuery #2014年5月27日view:5497
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

本章小编介绍下关于队列的操作
先来看api的一些介绍 $.queue(), $().queue()

jQuery.extend({
    //...
    //函数入队,返回队列
    queue: function( elem, type, data ) {},
    //函数出队,并执行
    dequeue: function( elem, type ) {}
});
jQuery.fn.extend({
    //函数入队,返回队列
    queue: function( type, data ) {},
    //函数出队,并执行
    dequeue: function( type ) {},
    //设置延迟出队
    delay: function( time, type ) {},
    //清空队列
    clearQueue: function( type ) {},
    //...
});

各位要是对照过源码的话可能要吐槽了,先别急,这里确实少介绍了几个api我们下篇再说
来看个例子:

var obj = {};
$.queue(obj,'say',function(next){ alert('hello'); next(); });
$.queue(obj,'say',function(){ alert('world'); });
$.dequeue(obj,'say');

我们来解释下:
使用 $.queue 给 obj对象 添加了一个 'say' 队列,并添加两个函数
使用 $.dequeue 触发 obj对象 的 'say' 队列
队列函数在调用时jQ会传入一个函数[next],执行函数函数时,会触发当前队列的下一个函数
当然, 最后一个就不需要接受了。

jQuery.extend({
    /*
        我们先来稍解释下,在前一篇,小编介绍了jQ的数据管理,
        那这里呢,jQ就是把队列相关信息保存在了对象映射的jQ缓存中【如果是js对象,则保存在自身上】
    */
    queue: function( elem, type, data ) {
        var q;
        if ( elem ) {
            // 拼接传入的事件类型 
            // eg: { sayqueue: [ fn, fn, fn, ... ] }
            type = ( type || "fx" ) + "queue";
            // 取出事件队列, 数组
            q = jQuery._data( elem, type );
            // 如果传入了要绑定的函数
            if ( data ) {
                //如果队列为空 || 传入的是一个数组,一组事件
                //则设置||重置 绑定事件队列
                if ( !q || jQuery.isArray(data) ) {
                    // 这里小编要道个歉,makeArray()在之前小编根据源码解释为数组合并
                    // 其实这个api的本意是可以将类似数组或者不是数组的东西强制转换成一个数组然后返回
                    // 在下不才,误导大家了,抱歉
                    q = jQuery._data( elem, type, jQuery.makeArray(data) );
                //否则直接追加到队列后即可
                } else {
                    q.push( data );
                }
            }
            //返回队列
            return q || [];
        }
    },
    //函数出队,并执行
    dequeue: function( elem, type ) {
        type = type || "fx";
            //取出事件列表
        var queue = jQuery.queue( elem, type ),
            //取出第一个事件
            fn = queue.shift(),
            hooks = {};
        //如果取到的是一个占位符,则舍弃再从队列取出一个
        //只有动画队列会设置占位符,表示动画正在执行中
        //请暂时忽略这个if代码段
        if ( fn === "inprogress" ) {
            fn = queue.shift();
        }
        if ( fn ) {
            //设置占位符表示函数在执行中
            //请暂时忽略这个if代码段
            if ( type === "fx" ) {
                queue.unshift( "inprogress" );
            }
            //设置一个数据 表示 改类型队列正在执行中
            jQuery._data( elem, type + ".run", hooks );
            //触发执行取出的函数,传入一个函数,执行这个函数效果是 触发下一个函数执行
            //这里的第二个匿名函数就是小编上面说的 next,可以看出来本质就是在此执行了dequeue
            fn.call( elem, function() {
                jQuery.dequeue( elem, type );
            }, hooks );
            //在事件执行时,hooks参数,可以用来存储一些信息,这个对象可以让用户在队列执行时保存一些信息
            //在下一个函数执行之前,可以使用: $._data( elem, type+".run" );
            //那么,有什么用~? 小编也不知道,至少暂时不知道,后面的代码中遇到了使用时,小编还会再介绍。
        }
        //当队列为空的时候:
        //移除 type+"queue" 和 type+".run" 两个数据参数
        if ( !queue.length ) {
            //最后一个true意味着是删除jq系统内部绑定的数据
            //这里小编在多解释下,这个要被删除的可以最终拼接出来是这样的 "sayqueue say.run"
            //在removeData函数中会被切割成数组,也就是删除这两个key,
            //这里最后传入一个key,目的是告诉jQ删除的是系统级别的key,如果不传入的话,则是删除用户自定义的数据
            //这个在前一篇数据管理中小编提到过的,这里废话下哈
            jQuery.removeData( elem, type + "queue " + type + ".run", true );
            handleQueueMarkDefer( elem, type, "queue" );
        }
    }
});

感谢您的阅读,欢迎留言:提问,交流,斧正;

评论
发表评论
暂无评论
WRITTEN BY
前端狮子
JS前端开发工程师 :喜欢研究js,nodejs,html5; 希望结交更多朋友~
TA的新浪微博
PUBLISHED IN
# 菜鸟解读 jQuery #

本栏解读的jQ为1.7.2版本。 本人也是刚开始读起源码,在这里分享下成长的心得。 本人能力有限,也是接触JS不久的初学者,定会有不少解析不全不够明朗【甚至BUG】的地方, 希望各位牛牛多多留言斧正 感谢阅读 ps:由于工作不定时繁忙,本人也无法定期更新,但是会尽量抽时间学习,分享给大家

我的收藏