jquery源码解析--queue队列

queue队列是jquery库的内部实现的基础设施。队列主要是animate动画依赖的基础设施,整个jquery中队列仅供给动画用

queue队列简介

队列是一种特殊的线性表,是属于先进先出,而且只允许在表的前端进行删除操作(出队),在表的后端(队尾)进行插入操作(入队)

queue的基本使用

queue队列即是工具方法,也是实例方法,queue方法是将函数添加到队列中,dequeue方法是将函数从队列中取出并执行该函数。

$('div').queue('q',[function(next){alert('队列函数1')},function(next){alert('队列函数2')},function(next){alert('队列函数3')}])

var queue = $('div').queue(); // 获取第一个div元素的队列"q"
var queue1 = $("#n1").queue("q");
var queue2 = $("#n2").queue("q");
var queue3 = $("#n3").queue("q");
document.writeln( queue === queue1 ); // true
document.writeln( queue === queue2 ); // false
document.writeln( queue === queue3 ); // false

document.writeln( queue.length ); // 3
$('div').dequeue('q');

queue源码解析

jQuery.extend({
/**
     * 显示或操作匹配的元素上待执行的函数列队
     * @param  {DOM元素} elem 需要操作的dom节点
     * @param  {string} type 队列名称 默认为'fxqueue'
     * @param  {function|arr} 队列中的方法可以为一个函数 也可以为多个函数组成的数组
     * @return {[type]}      [description]
     */
queue: function( elem, type, data ) {
    var queue;

    if ( elem ) {
        type = ( type || "fx" ) + "queue";
        queue = jQuery._data( elem, type );//返回元素中通过data存放的队列

        // Speed up dequeue by getting out quickly if this is just a lookup
        // 如果data存在 执行setting操作
        if ( data ) {
            if ( !queue || jQuery.isArray(data) ) {
                //如果队列不存在 或data是数组 重新设置队列
                queue = jQuery._data( elem, type, jQuery.makeArray(data) );
            } else {
                //如果队列存在 且data为单个回调函数 则将data存入queue中
                queue.push( data );
            }
        }
        return queue || [];
    }
},


dequeue: function( elem, type ) {
    type = type || "fx";
    //先获取队列
    var queue = jQuery.queue( elem, type ),
        startLength = queue.length,
        //取出队列中的第一项
        fn = queue.shift(),
        //当data中的startLength为0时 将data删除
        hooks = jQuery._queueHooks( elem, type ),

        //出站操作
        next = function() {
            jQuery.dequeue( elem, type );
        };

    // If the fx queue is dequeued, always remove the progress sentinel
    // inprogreess作用是自动执行队列中的第一个函数
    if ( fn === "inprogress" ) {
        fn = queue.shift();
        startLength--;
    }

    if ( fn ) {

        // Add a progress sentinel to prevent the fx queue from being
        // automatically dequeued
        //对于不是第一个添加 inprogress 执行fx
        if ( type === "fx" ) {
            //添加inprogress
            queue.unshift( "inprogress" );
        }

        // clear up the last queue stop function
        delete hooks.stop;
        fn.call( elem, next, hooks );
    }
    //执行删除缓存操作

    if ( !startLength && hooks ) {
        hooks.empty.fire();
    }
},

// not intended for public consumption - generates a queueHooks object, or returns the current one
//删除data的callbacks
_queueHooks: function( elem, type ) {
    var key = type + "queueHooks";
    return jQuery._data( elem, key ) || jQuery._data( elem, key, {
        empty: jQuery.Callbacks("once memory").add(function() {
            jQuery._removeData( elem, type + "queue" );
            jQuery._removeData( elem, key );
        })
    });
}
});

jQuery.fn.extend({
queue: function( type, data ) {
    var setter = 2;

    //type省略的情况 第一个参数为function类型 参数长度为1
    if ( typeof type !== "string" ) {
        data = type;
        type = "fx";
        setter--;
    }

    //如果参数总数小于setting 返回第一个元素的queue
    if ( arguments.length < setter ) {
        return jQuery.queue( this[0], type );
    }

    return data === undefined ?
        this :
        this.each(function() {
            var queue = jQuery.queue( this, type, data );

            // ensure a hooks for this queue
            jQuery._queueHooks( this, type );

            // 如果type为fx并且队列中的第一个值不为inprogress 就自动执行第一个函数
            if ( type === "fx" && queue[0] !== "inprogress" ) {
                jQuery.dequeue( this, type );
            }
        });
},
dequeue: function( type ) {
    return this.each(function() {
        jQuery.dequeue( this, type );
    });
},
clearQueue: function( type ) {
    return this.queue( type || "fx", [] );
},
// Get a promise resolved when queues of a certain type
// are emptied (fx is the type by default)
// 全部队列执行完后可以执行promise
promise: function( type, obj ) {
    var tmp,
        count = 1,//记录有多少个执行的队列
        defer = jQuery.Deferred(),
        elements = this,
        i = this.length,
        resolve = function() {
            // 累减为0 执行if
            if ( !( --count ) ) {
                defer.resolveWith( elements, [ elements ] );
            }
        };

    if ( typeof type !== "string" ) {
        obj = type;
        type = undefined;
    }
    type = type || "fx";

    while ( i-- ) {
        tmp = jQuery._data( elements[ i ], type + "queueHooks" );
        // 如果tmp不为空 队列值加1
        if ( tmp && tmp.empty ) {
            count++;
            tmp.empty.add( resolve );
        }
    }
    resolve();
    return defer.promise( obj );
}
});
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值