简介:
在data的基础上,在数据对象中添加一个一个属性,属性内容指定是数组队列。
代码大体框架:
jQuery.extend({
queue: function( elem, type, data ) {
},
dequeue: function( elem, type ) {
},
_queueHooks: function( elem, type ) {
}
});
jQuery.fn.extend({
queue: function( type, data ) {
},
dequeue: function( type ) {
},
delay: function( time, type ) {
},
clearQueue: function( type ) {
},
promise: function( type, obj ) {
}
});
代码解析:
jQuery.extend:
使用$调用的jQuery队列相关方法。
-
queue:
queue: function( elem, type, data ) {
var queue;
if ( elem ) {
type = ( type || "fx" ) + "queue";
queue = data_priv.get( elem, type );
if ( data ) {
if ( !queue || jQuery.isArray( data ) ) {
queue = data_priv.access( elem, type, jQuery.makeArray(data) );
} else {
queue.push( data );
}
}
return queue || [];
}
},
输入三个参数,挂载数据的元素elem;属性名type;数据data。
判断元素是否存在,只有存在的基础上,才能有挂载。存在的话进行队列的创建和数据的添加。
为type赋值,type = ( type || "fx" ) + "queue",以对应队列在数据对象中的属性名。(不存在的话,就是默认fxqueue)
在data_priv实例对象中,取出对应的队列数据。在判断data是否存在,不存在的话,直接返回队列数据,存在的话,再次判断,如果队列不存在,就是用data_priv.access创建一个,将数据添加进行,如果队列存在,但是data是数组,就让data的数据覆盖原来的队列,如果队列存在,data不是数组,就使用push将元素添加到队列中,
-
_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 ] );
})
});
}
传入两个参数,挂载数据的元素elem;属性名type;
创建属性名key,为key = type + "queueHooks"。
返回结果,先使用data_priv.get,获取挂载在元素上的数据对象中,属性名为key的属性内容;如果不存在的话,就使用data_priv.access,为挂载在元素上的数据对象添加属性key内容是一个对象对象内存在属性empty,内容是一个标识为once memory的回调函数,为这个对调函数添加一个函数,data_priv.remove( elem, [ type + "queue", key ] );,即使用data_priv.remove移除挂载在元素上的数据对象中的属性type + "queue", key。
-
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 ( fn === "inprogress" ) {
fn = queue.shift();
startLength--;
}
if ( fn ) {
if ( type === "fx" ) {
queue.unshift( "inprogress" );
}
delete hooks.stop;
fn.call( elem, next, hooks );
}
if ( !startLength && hooks ) {
hooks.empty.fire();
}
},
输入两个个参数,挂载数据的元素elem;属性名type;(应该通常用于内部)
对type进行重新赋值,type如果存在就是type,不存在的话,就是默认值"fx"。
之后创建相关变量:
- queue:通过jQuery.queue,创建或者获取挂载在元素上的队列
- startLength:队列长度
- fn:数组的shift()执行结果,作用是移除数组中的第一个项并返回该项,同时将数组长度减1。(也就是说,以及移除第一项了)
- hooks:_queueHooks返回的一个callback函数的self结果。
- next:函数,内部执行jQuery.dequeue( elem, type )
如果第一个被移除的元素是字符串"inprogress"的话,就再次执行queue.shift(),startLength减一。
如果fn存在的话,如果type等于默认的字符串"fx",就将"inprogress"字符串压入队列首项。
之后删除hooks的stop属性,然后使用call执行,将elem作为this指向,传入参数next, hooks(使用dequeue移除元素的话, 必须是函数,不然会报错。所以一般使用队列处理函数。)
最后,如果startLength为0且hooks存在的话,执行hooks.empty.fire();,删除挂载在元素上的数据对象中的队列数组。
jQuery.fn.extend:
使用$()调用的jQuery队列相关方法。
-
queue:
queue: function( type, data ) {
var setter = 2;
if ( typeof type !== "string" ) {
data = type;
type = "fx";
setter--;
}
if ( arguments.length < setter ) {
return jQuery.queue( this[0], type );
}
return data === undefined ?
this :
this.each(function() {
var queue = jQuery.queue( this, type, data );
jQuery._queueHooks( this, type );
if ( type === "fx" && queue[0] !== "inprogress" ) {
jQuery.dequeue( this, type );
}
});
},
传入两个参数,type代表属性;data代表数据。
创建变量setter,初始化为2,用来判定传入的参数类型。
如果type的类型不是字符串的话(为对象),将type赋值给data,然后type赋值为默认的"fx",setter减一。
如果传入的参数数量少于setter的话,(只传入一个字符串)直接返回对应字符串的队列数据。
返回结果,
- 如果data等于undefined的话(type是字符串,但是data传入了undefined)返回jQuery实例对象;
- 如果data不等于undefined的话,实例jQuery执行each函数,为每个实例中的节点元素挂载数据对象,再为对象添加队列数组属性。调用执行jQuery._queueHooks。如果type等于默认的'fx'且队列的第一个元素不为"inprogress",(应该是针对内部的动画,复用性太强,导致解读就比较费劲)执行jQuery.dequeue( this, type ),移除数据。
-
dequeue
dequeue: function( type ) {
return this.each(function() {
jQuery.dequeue( this, type );
});
},
传入type,遍历jQuery实例,每个元素使用jQuery.dequeue移除数据。
-
delay:
delay: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
type = type || "fx";
return this.queue( type, function( next, hooks ) {
var timeout = setTimeout( next, time );
hooks.stop = function() {
clearTimeout( timeout );
};
});
},
用于延迟函数的执行,传入time表示延迟时间和type属性名。
返回,在队列中传入一个函数,函数传入next执行函数,hooks回调对象。
创建一个定时器,传入执行函数next,时间time。
为hooks添加一个属性stop,用于清除定时器。
-
clearQueue:
clearQueue: function( type ) {
return this.queue( type || "fx", [] );
},
清空移除队列中的所有数据,转为空数组。
-
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 );
}
等队列中的所有函数都执行完毕了,在执行传入的函数。
创建变量,tmp,表示队列数组;count,表示队列中需要执行的函数数量;defer,jQuery.Defferred()对象;elements挂载的元素数组(jQuery实例对象);i,表示元素长度;resolve,执行存储在defer内的函数,只有count大于1,就会执行defer中的函数。
如果type的类型不是字符串的话,将type赋值给obj,type赋值为undefined。
对type再赋值,如果存在就不变,不存在的话,就是"fx"默认值。
while循环 i 次,每次,将data_priv对应type + "queueHooks"的队列数组赋值给tmp。
如果tmp且tmp.empty存在就count++,并且添加resolve(由于是"once memory"标识)
调用resolve(),执行函数。
返回defer.promise( obj )。