Jquery queue源码分析

来源:互联网 发布:南木梁知小说百度云盘 编辑:程序博客网 时间:2024/05/01 16:23
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 );
 }
});

原创粉丝点击