热门关键字:
jquery > jquery教程 > jquery教程 > jQuery1.8.2源码解析之jQuery.Callbacks

jQuery1.8.2源码解析之jQuery.Callbacks

409
作者:管理员
发布时间:2020/2/17 18:10:52
评论数:0
转载请自觉注明原文:http://www.jq-school.com/Show.aspx?id=825

  jQuery1.8.2源码解析之jQuery.Callbacks,已经在代码中添加了详细的注释,有需要的朋友看下边的代码就可以了。这样在使用时就方便了许多。

  代码:

  CopytoClipboardLiehuo.NetCodes引用的内容:[www.3672js.com]//StringtoObjectoptionsformatcache

  //是对option的一个缓存,避免每次都要createOptions

  //每一个option类似这样

  //{

  //memory:true

  //,once:true

  //,...

  //}

  varoptionsCache={};

  //ConvertString-formattedoptionsintoObject-formattedonesandstoreincache

  functioncreateOptions(options){

  varobject=optionsCache[options]={};

  jQuery.each(options.split(core_rspace),function(_,flag){

  object[flag]=true;

  });

  returnobject;

  }

  /*

  *Createacallbacklistusingthefollowingparameters:

  *

  *options:anoptionallistofspace-separatedoptionsthatwillchangehow

  *thecallbacklistbehavesoramoretraditionaloptionobject

  *

  *Bydefaultacallbacklistwillactlikeaneventcallbacklistandcanbe

  *"fired"multipletimes.

  *

  *Possibleoptions:

  *

  *once:willensurethecallbacklistcanonlybefiredonce(likeaDeferred)

  *

  *memory:willkeeptrackofpreviousvaluesandwillcallanycallbackadded

  *afterthelisthasbeenfiredrightawaywiththelatest"memorized"

  *values(likeaDeferred)

  *

  *unique:willensureacallbackcanonlybeaddedonce(noduplicateinthelist)

  *

  *stopOnFalse:interruptcallingswhenacallbackreturnsfalse

  *

  */

  jQuery.Callbacks=function(options){

  //ConvertoptionsfromString-formattedtoObject-formattedifneeded

  //(wecheckincachefirst)

  //options也可以是一个对象

  options=typeofoptions==="string"?

  (optionsCache[options]||createOptions(options)):

  jQuery.extend({},options);

  var//Lastfirevalue(fornon-forgettablelists)

  memory,

  //Flagtoknowiflistwasalreadyfired

  fired,

  //Flagtoknowiflistiscurrentlyfiring

  firing,

  //Firstcallbacktofire(usedinternallybyaddandfireWith)

  firingStart,

  //Endoftheloopwhenfiring

  firingLength,

  //Indexofcurrentlyfiringcallback(modifiedbyremoveifneeded)

  firingIndex,

  //Actualcallbacklist

  list=[],

  //Stackoffirecallsforrepeatablelists

  //只有在没有设置了once时,stack才存在

  //stack用来存储参数信息(此时函数列表已经处于firing状态,必须将其他地方调用fire时的参数存储,之后再至此执行fire

  stack=!options.once&&[],

  //Firecallbacks

  fire=function(data){

  //如果设置memory,那么每一次fire的数据将会被保存在memory中,作为下次调用add时参数

  memory=options.memory&&data;

  fired=true;

  firingIndex=firingStart||0;

  //重置fireStarting为0,因为add操作(memory)可能改变它

  firingStart=0;

  firingLength=list.length;

  firing=true;

  for(;list&&firingIndex<firingLength;firingIndex++){

  //如果设置了stopOnFalse参数,那么当函数列表中有某个函数返回false时,停止后面函数的执行,并且取消memory(如果设置了)

  if(list[firingIndex].apply(data[0],data[1])===false&&options.stopOnFalse){

  memory=false;//Topreventfurthercallsusingadd

  break;

  }

  }

  firing=false;

  if(list){

  //如果stack存在,那么将之前存储的第一个参数取出,继续fire,直到stack为空

  if(stack){

  if(stack.length){

  fire(stack.shift());

  }

  //如果stack不存在(即设置了once)

  //那么如果设置了memory,那么将之前函数列表清空,也就是说memory还在,add操作可以处罚函数立即执行

  }elseif(memory){

  list=[];

  }else{

  self.disable();

  }

  }

  },

  //ActualCallbacksobject

  //实际返回的Callbacks对象

  self={

  //Addacallbackoracollectionofcallbackstothelist

  //添加函数或者函数集(数组或者伪数组)到函数列表中去

  add:function(){

  if(list){

  //First,wesavethecurrentlength

  varstart=list.length;

  (functionadd(args){

  jQuery.each(args,function(_,arg){

  vartype=jQuery.type(arg);

  //如果arg是函数

  //如果设置unique,则在list中查找是否函数已存在,若存在忽略掉,否则push进list

  //如果没有设置unique,则直接push进list

  if(type==="function"&&(!options.unique||!self.has(arg))){

  list.push(arg);

  //如果arg是数组或者伪数组,则递推push进list

  }elseif(arg&&arg.length&&type!=="string"){

  //Inspectrecursively

  //递归(成员为函数集)

  add(arg);

  }

  });

  })(arguments);

  //Doweneedtoaddthecallbackstothe

  //currentfiringbatch?

  //在添加函数(集)时

  //如果函数列表正在依次执行回调函数(即firing状态),在某一个callback中执行add(fn)操作

  //那么立即修改fireLength以便fire时函数列表能够执行到刚添加的函数(集)

  if(firing){

  firingLength=list.length;

  //Withmemory,ifwe'renotfiringthen

  //weshouldcallrightaway

  //如果不是firing状态,并且设置了memory(肯定是在fired状态时才会执行这一步,因为memory是在fire一次后才会被负值)

  //此时memory已经是上次fire是传递的参数,那么将会直接执行刚添加的函数集,而无需fire

  }elseif(memory){

  firingStart=start;

  fire(memory);

  }

  }

  returnthis;

  },

  //Removeacallbackfromthelist

  //从函数列表中删除函数(集)

  remove:function(){

  if(list){

  jQuery.each(arguments,function(_,arg){

  varindex;

  //while循环的意义在于借助于强大的jQuery.inArray删除函数列表中相同的函数引用(没有设置unique的情况)

  //jQuery.inArray将每次返回查找到的元素的index作为自己的第三个参数继续进行查找,直到函数列表的尽头

  //splice删除数组元素,修改数组的结构

  while((index=jQuery.inArray(arg,list,index))>-1){

  list.splice(index,1);

  //Handlefiringindexes

  //在函数列表处于firing状态时,最主要的就是维护firingLength和firgingIndex这两个值

  //保证fire时函数列表中的函数能够被正确执行(fire中的for循环需要这两个值)

  if(firing){

  if(index<=firingLength){

  firingLength--;

  }

  if(index<=firingIndex){

  firingIndex--;

  }

  }

  }

  });

  }

  returnthis;

  },

  //Controlifagivencallbackisinthelist

  //判断函数列表只能够是否包含给定的fn

  has:function(fn){

  returnjQuery.inArray(fn,list)>-1;

  },

  //Removeallcallbacksfromthelist

  //清空函数列表

  empty:function(){

  list=[];

  returnthis;

  },

  //Havethelistdonothinganymore

  //使函数列表作废(不能再做任何事情)

  disable:function(){

  list=stack=memory=undefined;

  returnthis;

  },

  //Isitdisabled?

  //判断是否函数列表是否disabled

  disabled:function(){

  return!list;

  },

  //Lockthelistinitscurrentstate

  lock:function(){

  stack=undefined;

  if(!memory){

  self.disable();

  }

  returnthis;

  },

  //Isitlocked?

  locked:function(){

  return!stack;

  },

  //Callallcallbackswiththegivencontextandarguments

  //和fire相似,不相同的是fireWith可以给定上下文参数

  //fire中就是调用fireWith中的context就是this(函数列表对象self)

  fireWith:function(context,args){

  args=args||[];

  args=[context,args.slice?args.slice():args];

  //首先至少fire一次

  //如果执行过一次了(fired),那么若stack存在(即没有设置once),将上下文环境和参数存储,否则什么都不做

  if(list&&(!fired||stack)){

  if(firing){

  stack.push(args);

  }else{

  fire(args);

  }

  }

  returnthis;

  },

  //Callallthecallbackswiththegivenarguments

  //依次执行函数列表中的函数

  fire:function(){

  self.fireWith(this,arguments);

  returnthis;

  },

  //Toknowifthecallbackshavealreadybeencalledatleastonce

  //判断是否函数列表fire过(哪怕只有一次)

  fired:function(){

  return!!fired;

  }

  };

  returnself;

  };





如果您觉得本文的内容对您的学习有所帮助:支付鼓励



关键字:jQuery
友荐云推荐