jQuery代码分析之四Queue

本文详细解析jQuery中的fn.queue和dequeue功能,包括如何在匹配元素上执行一组函数,以及如何实现链式动画处理。通过实例演示和代码分析,深入理解jQuery在动画处理中的队列管理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在博文jQuery代码分析之一中偶介绍了下animation的实现机制,怎样实现属性值的渐变?那么如果我们需要在一个元素上做链式animation时,jQuery是如何处理的呢?例如,有如下示范代码:

$("#div1").slideDown().fadeOut();

这里面涉及到的技术就是偶将在这篇文章中讲到的fn.queue。首先还是看下API定义

描述:定义将在匹配元素上执行的一组函数。

queue([queueName], newQueue)

queueName:queue的名字,默认值为fx,默认的fx queue也是jquery在做animation时默认存放回调函数的队列。

newQueue:用一组新的函数队列取代当前queue,如果传入空数组[],那就是把这个queue清空。

queue([queueName], callback(next))

callback(next):往队列里插入一个回调函数,注意它可以接受一个参数next,这个next是一个函数对象,其定义如下

next = function() {
				jQuery.dequeue( elem, type );
			};
因此我们可以实现一个这样的回调函数

$("#test").queue(function(next) {
    // Do some stuff...
    next();
});
因为fn.queue/dequeue是依赖于jQuery.queue/dequeue的,所以我们准备看看jQuery.queue/dequeue的实现。

jQuery.queue()的实现代码很直观,就是函数功能的翻译。那我们看看jQuery.dequeue()的实现,稍微复杂一点

	dequeue: function( elem, type ) {
        type = type || "fx";

        var queue = jQuery.queue( elem, type ),
            startLength = queue.length,
            fn = queue.shift(),
            hooks = jQuery._queueHooks( elem, type ),
            next = function() {
                jQuery.dequeue( elem, type );
            };

        // If the fx queue is dequeued, always remove the progress sentinel
        if ( fn === "inprogress" ) {
            fn = queue.shift();
            startLength--;
        }

        if ( fn ) {

            // Add a progress sentinel to prevent the fx queue from being
            // automatically dequeued
            if ( type === "fx" ) {
                queue.unshift( "inprogress" );
            }

            // clear up the last queue stop function
            delete hooks.stop;
            fn.call( elem, next, hooks );
        }

        if ( !startLength && hooks ) {
            hooks.empty.fire();
        }
    }
上面这段代码有几个地方需要另外解释下。

1. _queueHooks()是个什么东东?因为它涉及到Deferred object,所以我们先暂时把它理解作。。。Deferred object会在下一篇博文中介绍。

2. 为啥要在队列前面插入一个"inprogress"?

原来fn.queue是在jQuery.queue的基础上又做了一件事,

var queue = jQuery.queue( this, type, data );

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

if ( type === "fx" && queue[0] !== "inprogress" ) {
    jQuery.dequeue( this, type );
}
如果队列首不是"inprogress"的话,那就要执行出队列操作。然而每次调用jQuery.dequeue是,都会在队列首部插入一个"inprogress",这就保证了jQuery.dequeue只会被fn.queue调用一次,后面的调用会因为queue[0]=="inprogress"而不执行jQuery.dequeue(this, type)。那有人会问,怎样保证queue首部只有一个"inprogress"呢?答案很简单,jQuery.dequeue在做出对操作时,会检查队首是否为"inprogress",如果是的话,就会继续出对,直到遇到一个非"inprogress"值(通常为一个回调函数),或者直到队列为空。

关于queue与dequeue的用法可以参考 jQuery中queue和dequeue的用法


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值