jQuery.extend({
queue: function( elem, type, data ) {//存取type类型的队列数据,最后都会全部取出数据
var queue;
if ( elem ) {
type = ( type || "fx" ) + "queue";//类型默认是fx,估计光动画那里在用这个
queue = jQuery._data( elem, type );
if ( data ) {//如果data存在表示保存数据
if ( !queue || jQuery.isArray(data) ) {//如果本类型缓存里没数据或者data是一组数据,则先保存数据,再取
queue = jQuery._data( elem, type, jQuery.makeArray(data) );
} else {//如果data是一条数据,并且本类型缓存里有数据,则直接合并数据
queue.push( data );
}
}
return queue || [];//返回全部数据
}
},
dequeue: function( elem, type ) {//出列, 把方法取出来-----1,然后执行-----2
type = type || "fx";//类型默认还是fx
var queue = jQuery.queue( elem, type ),//先尝试取数据
startLength = queue.length,//数据总长度
fn = queue.shift(),//取出第一条数据-----1
hooks = jQuery._queueHooks( elem, type ),
next = function() {
jQuery.dequeue( elem, type );
};
if ( fn === "inprogress" ) {//对这个方法忽视
fn = queue.shift();//-----1
startLength--;
}
if ( fn ) {
if ( type === "fx" ) {//对动画类型进行单独处理
queue.unshift( "inprogress" );
}
delete hooks.stop;
fn.call( elem, next, hooks );//--------2
}
if ( !startLength && hooks ) {//如果未取出缓存数据,则直接清理本类型的缓存数据
hooks.empty.fire();
}
},
_queueHooks: function( elem, type ) {//这个钩子用来清理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", true );
jQuery.removeData( elem, key, true );
})
});
}
});
jQuery.fn.extend({
queue: function( type, data ) {
var setter = 2;
if ( typeof type !== "string" ) {//第一个参数可以是第二个参数,代表第一个参数是fx,这是jquery的特色
data = type;
type = "fx";
setter--;
}
if ( arguments.length < setter ) {//表示就传了一个参数还是字符串,则表示取出第一个jqeury对象的队列
return jQuery.queue( this[0], type );
}
return data === undefined ?//既然要赋值data就不能为空,为所有jqeury对象设置缓存
this :
this.each(function() {
var queue = jQuery.queue( this, type, data );
jQuery._queueHooks( this, type );
if ( type === "fx" && queue[0] !== "inprogress" ) {//对fx类型进行单独处理,满足一定要求则出队列
jQuery.dequeue( this, type );
}
});
},
dequeue: function( type ) {//出队,对所有jquery元素出队列
return this.each(function() {
jQuery.dequeue( this, type );
});
},
delay: function( time, type ) {//对一个方法延迟执行
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;//时间可以是jquery内部定的default, slow, fast类型,也可以自定义数字
type = type || "fx";//类型默认是fx
return this.queue( type, function( next, hooks ) {//返回一个延迟加载的方法
var timeout = setTimeout( next, time );
hooks.stop = function() {
clearTimeout( timeout );
};
});
},
clearQueue: function( type ) {//注销本类型的队列
return this.queue( type || "fx", [] );
},
promise: function( type, obj ) {//返回一个deferred对象
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 = jQuery._data( elements[ i ], type + "queueHooks" );
if ( tmp && tmp.empty ) {
count++;
tmp.empty.add( resolve );
}
}
resolve();
return defer.promise( obj );
}
});