首页 > 代码库 > jquery源码01---(2880 , 3042) Callbacks : 回调对象 : 对函数的统一管理

jquery源码01---(2880 , 3042) Callbacks : 回调对象 : 对函数的统一管理

// optionsCache : { ‘once memory‘ : { once : true , memory : true } }
var optionsCache = {};

// once memory,options.match( core_rnotwhite )=[once, memory],function( _, flag )={once:true,memory:true}
function createOptions( options ) {
    var object = optionsCache[ options ] = {};//中括号就是json的点,没有点了。
    jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
        object[ flag ] = true;
    });
    return object;
}

/*
    var cb = $.Callbacks();
    function aaa(){
        alert(1);
    }
    cb.add(aaa);
    (function(){
        function bbb(){
            alert(2);
        }
        cb.add(bbb);
    })();
    cb.fire();//1  2
 */
jQuery.Callbacks = function( options ) {//类的静态方法
    //options 可选: once memory unique stopOnFalse
    //方法:add remove has empty disable disabled lock locked fireWith fire fired
    //什么都不写走jQuery.extend( {}, options ),返回空{},不这样写,如果options===undefined,后面还要做兼容。
    options = typeof options === "string" ?
        ( optionsCache[ options ] || createOptions( options ) ) :
        jQuery.extend( {}, options );//options={once:true,memory:true}

    var  
        memory,
        fired,
        firing,
        firingStart,
        firingLength,
        firingIndex,
        // 添加的所有方法
        list = [],
        stack = !options.once && [],
        fire = function( data ) {
            memory = options.memory && data;//有memory返回true
            fired = true;//触发开始
            firingIndex = firingStart || 0;
            firingStart = 0;
            firingLength = list.length;
            firing = true;
            for ( ; list && firingIndex < firingLength; firingIndex++ ) {
                if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {// 函数返回false,有stopOnFalse属性就不向下执行
                    memory = false; //memory也要置为false
                    break;
                }
            }
            firing = false;//触发结束
            if ( list ) {
                if ( stack ) {
                    if ( stack.length ) {
                        fire( stack.shift() );
                    }
                } else if ( memory ) {
                    list = [];
                } else {
                    self.disable();
                }
            }
        },
        self = {//对外部接口
            add: function() {
                if ( list ) {//list一上来是空数组,会返回真,
                    var start = list.length;
                    (function add( args ) {//args是形参
                        jQuery.each( args, function( _, arg ) {//遍历传进来的多个方法名,
                            var type = jQuery.type( arg );
                            if ( type === "function" ) {
                                if ( !options.unique || !self.has( arg ) ) {//不是unioqye,或者是unipue但是没有
                                    list.push( arg );
                                }
                            } else if ( arg && arg.length && type !== "string" ) {//数组,嵌套
                                add( arg );
                            }
                        });
                    })( arguments );//arguments是实参,方法名aaa,
                    if ( firing ) {
                        firingLength = list.length;
                    } else if ( memory ) {//第一次没有赋值是undefined,
                        firingStart = start;
                        fire( memory );
                    }
                }
                return this;
            },
            remove: function() {
                if ( list ) {
                    jQuery.each( arguments, function( _, arg ) {//可以删除多个
                        var index;
                        while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
                            list.splice( index, 1 );//删除
                            if ( firing ) {
                                if ( index <= firingLength ) {
                                    firingLength--;
                                }
                                if ( index <= firingIndex ) {
                                    firingIndex--;
                                }
                            }
                        }
                    });
                }
                return this;
            },
            has: function( fn ) {
                return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
            },
            empty: function() {
                list = [];
                firingLength = 0;
                return this;
            },
            disable: function() {
                list = stack = memory = undefined;
                return this;
            },
            disabled: function() {
                return !list;
            },
            lock: function() {
                stack = undefined;
                if ( !memory ) {
                    self.disable();
                }
                return this;
            },
            locked: function() {
                return !stack;
            },
            fireWith: function( context, args ) {
                if ( list && ( !fired || stack ) ) {
                    args = args || [];
                    args = [ context, args.slice ? args.slice() : args ];
                    if ( firing ) {
                        stack.push( args );
                    } else {
                        fire( args );
                    }
                }
                return this;
            },
            fire: function() {
                self.fireWith( this, arguments );//cb.fire(‘hello‘);
                return this;
            },
            fired: function() {
                return !!fired;
            }
        };

    return self;
};

 

jquery源码01---(2880 , 3042) Callbacks : 回调对象 : 对函数的统一管理