jQuery1.8.2源码解析之jQuery.Callbacks
发布时间:2018-08-29 05:43:28 所属栏目:传媒 来源:站长网
导读:jQuery1.8.2源码解析之 jQuery .Callbacks,已经在代码中添加了详细的注释,有需要的朋友看下边的代码就可以了。这样在使用时就方便了许多。 代码: Copy to Clipboard 引用的内容:[www.veryhuo.com]// String to Object options format cache // 是对opt
jQuery1.8.2源码解析之jQuery.Callbacks,已经在代码中添加了详细的注释,有需要的朋友看下边的代码就可以了。这样在使用时就方便了许多。 代码: Copy to Clipboard![]() // 是对option的一个缓存,避免每次都要createOptions // 每一个option类似这样 // { // memory : true // ,once : true // ,... // } var optionsCache = {}; // Convert String-formatted options into Object-formatted ones and store in cache function createOptions( options ) { var object = optionsCache[ options ] = {}; jQuery.each( options.split( core_rspace ), function( _, flag ) { object[ flag ] = true; }); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) // options也可以是一个对象 options = typeof options === "string" ? ( optionsCache[ options ] || createOptions( options ) ) : jQuery.extend( {}, options ); var // Last fire value (for non-forgettable lists) memory, // Flag to know if list was already fired fired, // Flag to know if list is currently firing firing, // First callback to fire (used internally by add and fireWith) firingStart, // End of the loop when firing firingLength, // Index of currently firing callback (modified by remove if needed) firingIndex, // Actual callback list list = [], // Stack of fire calls for repeatable lists // 只有在没有设置了once时,stack才存在 // stack用来存储参数信息(此时函数列表已经处于firing状态,必须将其他地方调用fire时的参数存储,之后再至此执行fire stack = !options.once && [], // Fire callbacks 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; // To prevent further calls using add break; } } firing = false; if ( list ) { // 如果stack存在,那么将之前存储的第一个参数取出,继续fire,直到stack为空 if ( stack ) { if ( stack.length ) { fire( stack.shift() ); } // 如果stack不存在(即设置了once) // 那么如果设置了memory,那么将之前函数列表清空,也就是说memory还在,add操作可以处罚函数立即执行 } else if ( memory ) { list = []; } else { self.disable(); } } }, // Actual Callbacks object // 实际返回的Callbacks对象 self = { // Add a callback or a collection of callbacks to the list // 添加函数或者函数集(数组或者伪数组)到函数列表中去 add: function() { if ( list ) { // First, we save the current length var start = list.length; (function add( args ) { jQuery.each( args, function( _, arg ) { var type = 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 } else if ( arg && arg.length && type !== "string" ) { // Inspect recursively // 递归(成员为函数集) add( arg ); } }); })( arguments ); // Do we need to add the callbacks to the // current firing batch? // 在添加函数(集)时 // 如果函数列表正在依次执行回调函数(即firing状态),在某一个callback中执行add(fn)操作 // 那么立即修改fireLength以便fire时函数列表能够执行到刚添加的函数(集) if ( firing ) { firingLength = list.length; // With memory, if we're not firing then // we should call right away // 如果不是firing状态,并且设置了memory(肯定是在fired状态时才会执行这一步,因为memory是在fire一次后才会被负值) // 此时memory已经是上次fire是传递的参数,那么将会直接执行刚添加的函数集,而无需fire } else if ( memory ) { firingStart = start; fire( memory ); } } return this; }, // Remove a callback from the list // 从函数列表中删除函数(集) remove: function() { if ( list ) { jQuery.each( arguments, function( _, arg ) { var index; // while循环的意义在于借助于强大的jQuery.inArray删除函数列表中相同的函数引用(没有设置unique的情况) // jQuery.inArray将每次返回查找到的元素的index作为自己的第三个参数继续进行查找,直到函数列表的尽头 // splice删除数组元素,修改数组的结构 while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes // 在函数列表处于firing状态时,最主要的就是维护firingLength和firgingIndex这两个值 // 保证fire时函数列表中的函数能够被正确执行(fire中的for循环需要这两个值) if ( firing ) { if ( index <= firingLength ) { firingLength--; } if ( index <= firingIndex ) { firingIndex--; } } } }); } return this; }, // Control if a given callback is in the list // 判断函数列表只能够是否包含给定的fn has: function( fn ) { return jQuery.inArray( fn, list ) > -1; }, // Remove all callbacks from the list // 清空函数列表 empty: function() { list = []; return this; }, // Have the list do nothing anymore // 使函数列表作废(不能再做任何事情) disable: function() { list = stack = memory = undefined; return this; }, // Is it disabled? // 判断是否函数列表是否disabled disabled: function() { return !list; }, // Lock the list in its current state lock: function() { stack = undefined; if ( !memory ) { self.disable(); } return this; }, // Is it locked? locked: function() { return !stack; }, // Call all callbacks with the given context and arguments // 和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 ); } } return this; }, // Call all the callbacks with the given arguments // 依次执行函数列表中的函数 fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once // 判断是否函数列表fire过(哪怕只有一次) fired: function() { return !!fired; } }; return self; }; (编辑:焦作站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |