//对外接口
jQuery.extend({
queue: function( elem, type, data ) {//入队。元素、队列名字、存进去的函数
//jQuery.queue( this, type, function( next, hooks ) {})
var queue; if ( elem ) {
type = ( type || "fx" ) + "queue";//不写队列名字就是fx
// $.queue( document , 'q1' , aaa||[aaa,bbb] );
queue = data_priv.get( elem, type );//get方法var cache = this.cache[ this.key( elem ) ];return type === undefined ? cache : cache[ type ];key方法return unlock = elem[ this.expando ];根据元素的唯一标识expando获取在data_priv对象中缓存中的1,2,3,4这个unlock数字,根据unlock这个数字获取cache中的json,根据type获取json中的值
/*
data_priv = {
1(document.203089541586732714850=1):{
name(type):'哈哈'(queue),
q1queue(type):...(queue数组),
}
}
*/ // Speed up dequeue by getting out quickly if this is just a lookup
if ( data ) {//函数名
if ( !queue || jQuery.isArray( data ) ) {//queue没有(函数是不是数组)或者queue有但是函数是数组,注意是数组就会把之前的全部覆盖。
/*
$.queue( document , 'q1' , aaa );
$.queue( document , 'q1' , bbb );
$.queue( document , 'q1' , [ccc] );
*/
queue = data_priv.access( elem, type, jQuery.makeArray(data) );
} else {//queue有(说明q1队列之前加过)并且函数不是数组直接push,注意queue没有的时候queue始终存的是一个数组
queue.push( data );
}
}
return queue || [];
}
}, dequeue: function( elem, type ) {
type = type || "fx";
//只能写jQuery.queue(),不能写queue(),queue()是jQuery类的静态方法,只能通过静态方式调用。
/*
jQuery.extend( {a:function(){alert(1)},b:function(){jQuery.a();}} )
$.b();
*/
var queue = jQuery.queue( elem, type ),//得到type对应的值,是一个数组,
startLength = queue.length,
fn = queue.shift(),//去除数组第一个
hooks = jQuery._queueHooks( elem, type ),
next = function() {
jQuery.dequeue( elem, type );//下一个,不能直接写dequeue,这行语句还没执行完时dequeue是不存在的
}; // 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" );//inprogress添进去
} // clear up the last queue stop function
delete hooks.stop;
fn.call( elem, next, hooks );//出队的函数执行,
} if ( !startLength && hooks ) {
hooks.empty.fire();
}
}, /*
data_priv = {
1(elem:document.203089541586732714850=1):{
name(type):'哈哈'(queue),
q1queue(type):...(queue数组),
}
}
*/
_queueHooks: function( elem, type ) {
var key = type + "queueHooks";
//有就获取,没有key,value都存在value是json就追加
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 ] );
})
});
}
}); jQuery.fn.extend({
//this.queue( type, function( next, hooks ) {
//$('#div').queue('q1',bbb);
queue: function( type, data ) {
var setter = 2;
//$('#div').queue(bbb);
if ( typeof type !== "string" ) {//只传了一个函数,没有type
data = type;
type = "fx";
setter--;
}
///console.log( $('#div').queue('q1') ); 查看
if ( arguments.length < setter ) {
return jQuery.queue( this[0], type );//静态方法调用
} return data === undefined ?
this :
this.each(function() {//$('#div')是一个数组,对每一个设置
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 );//第一个入队然后立即出队,调用
}
});
},
dequeue: function( type ) {
return this.each(function() {
jQuery.dequeue( this, type );//每一个出队
});
}, //.delay(2000)
/*
jQuery.fx.speeds = {
slow: 600,
fast: 200,
// Default speed
_default: 400
};
*/
//jQuery.fx = Tween.prototype.init;
delay: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
type = type || "fx";
//queue第二个参数是匿名函数,也添加进去
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 ) {
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 );
}
});