看jquery源码更好使用API

看jquery源码更好使用API

看过源码我们会发现其实jquey中有很多很好用的api我们没有使用过,今天我们一起看一下队列(queue)的源码,看一下都有哪些好用的API。
大纲如下图:

 看jquery源码更好使用API

queue有三个工具方法: queue,dqueue,_queueHooks,四个实例方法 :queue,dqueue,clearQueue,promise。jquery中很多模块都会同时有同名的工具和实例方法,但是实现功能的一般都是工具方法,而我们平常多用实例方法只因链式操作方便。
我们来看一下它们之间的关系:

 看jquery源码更好使用API

 工具方法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 || [];
  }
}
  1. 参数data存在,如果queue存在或都参数data为数组的话都会重新设置数据缓存
  2. 参数data存在,如果queue存在,则把数据push到queue里 像
这段代码很简单,其实就是把队列放在数据缓存里。 queue = data_priv.get( elem, type ), data_priv是缓存的实例对

工具私有方法_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

你可能感兴趣的:(jquery)