看jquery源码更好使用API
看过源码我们会发现其实jquey中有很多很好用的api我们没有使用过,今天我们一起看一下队列(queue)的源码,看一下都有哪些好用的API。
大纲如下图:
queue有三个工具方法: queue,dqueue,_queueHooks,四个实例方法 :queue,dqueue,clearQueue,promise。jquery中很多模块都会同时有同名的工具和实例方法,但是实现功能的一般都是工具方法,而我们平常多用实例方法只因链式操作方便。
我们来看一下它们之间的关系:
工具方法queue
queue: function( elem, type, data ) {var queue;
if ( elem ) {
type = ( type || "fx" ) + "queue";
queue = data_priv.get( elem, type );
// Speed up dequeue by getting out quickly if this is just a lookup
if ( data ) {
if ( !queue || jQuery.isArray( data ) ) {
queue = data_priv.access( elem, type, jQuery.makeArray(data) );
} else {
queue.push( data );
}
}
return queue || [];
}
}
- 参数data存在,如果queue存在或都参数data为数组的话都会重新设置数据缓存
- 参数data存在,如果queue存在,则把数据push到queue里 像
工具私有方法_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 ] );
})
});
}
这段代码虽少,但是很绕,这里的意思也就是说如果 data_priv.get( elem, key )存在则返回这个标志缓存,不存在则设置一个清空缓存的callBacks对象。
工具方法dqueue
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();
}
}
出队的逻辑是函数出队并执行,把下一个函数当参数传递过去,当是动画队列时自动出队执行第一个函数,当队列为零时清空缓存。
实例方法promise
promise: function( type, obj ) {
var tmp,
count = 1,
defer = jQuery.Deferred(),
elements = this,
i = this.length,
resolve = function() {
if ( !( --count ) ) {
defer.resolveWith( elements, [ elements ] );
}
};
if ( typeof type !== "string" ) {
obj = type;
type = undefined;
}
type = type || "fx";
while ( i-- ) {
tmp = data_priv.get( elements[ i ], type + "queueHooks" );
if ( tmp && tmp.empty ) {
count++;
tmp.empty.add( resolve );
}
}
resolve();
return defer.promise( obj );
}
这个方法是返回deferred的prmise对像,等队列中所有的函数执行完毕,执行回调,如 demo