jquery工具方法access详解

access : 多功能值操作(内部)

access方法可以使set/get方法在一个函数中体现。比如我们常用的css,attr都是调用了access方法。

css的使用方法:

$(selector).css(key)  //get
$(selector).css(key,valye)  //set
$(selector).css({key1:valye1,key2:value2})  //set
$(selector).css(function(){ ............. })  //set

access有一堆参数,炸一看蛮吓人的:

access: function( elems, fn, key, value, chainable, emptyGet, pass ) {

elems : 元素集合
fn : 回调
key : 键
value : 值
chaunable : 0:读取 1:设置
emptyGet : 该参数一般是不给的,当没有元素时返回undefined
pass : 字符串为真,函数为假

大致了解各参数后,我们看access方法的最下面可以发现,当chainable为1时表示设置,它直接返回元素集合方便链式调用,为0表示获取。

return chainable ?
    elems :

    // Gets
    bulk ?
        fn.call( elems ) :
        length ? fn( elems[0], key ) : emptyGet;

在获取的部分又做了判断,bulk是什么,我们回到access开头部分就知道了:

bulk = key == null,

当key没有的时候bulk为真,所以会走fn.call( elems ) 否则走length ? fn( elems[0], key ) : emptyGet;
当bulk为假时,先判断元素是否有长度,有的则执行回调,没有返回undefined。


了解get后,我们继续看set。set有3种形式:
1:键值对    $(selector).css(key,valye)
2:key为对象       $(selector).css({key1:valye1,key2:value2})
3:key为函数       $(selector).css(function(){ ....... })

我们回到access开头往下看,我们发现access整个代码块,除了最底部是处理get外,其余的部分都是在处理set。
下面的代码片段可以看出,if处理键为对象,else if处理非对象,在else if中又分别处理当参数为键值对和key为函数的2种形式。

// Sets many values
if ( key && typeof key === "object" ) {
   
    ..................

} else if ( value !== undefined ) {

    ....................

}

当键为对象时,它的处理方式是利用递归再执行一次access。

if ( key && typeof key === "object" ) {
    for ( i in key ) {
        jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
    }
    chainable = 1;

// Sets one value
} else if ( value !== undefined ) {

  ........................  

}

当键为非对象时,先判断值不为空,进入后做了4件事情:
1.如果值是函数,则exec为真。
2.如果键为空,则
                       1.当值为函数做了相应的处理
                       2.当值为字符串执行回调
3.循环元素集合执行回调
4.把chaunable设置为1,方便在return中进行处理

if ( key && typeof key === "object" ) {
    
    ......................

// Sets one value
} else if ( value !== undefined ) {
    // Optionally, function values get executed if exec is true
    exec = pass === undefined && jQuery.isFunction( value );

    if ( bulk ) {
        // Bulk operations only iterate when executing function values
        if ( exec ) {
            exec = fn;
            fn = function( elem, key, value ) {
                return exec.call( jQuery( elem ), value );
            };

        // Otherwise they run against the entire set
        } else {
            fn.call( elems, value );
            fn = null;
        }
    }

    if ( fn ) {
        for (; i < length; i++ ) {
            fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
        }
    }

    chainable = 1;
}

以上代码比较绕,其实一般情况是直接走情况3的,因为我们在设置css的时候key都是字符串。而情况2主要就是针对key为函数。

最后我们看下access完整的代码:

jQuery.extend({

    .............................

    // Multifunctional method to get and set values of a collection
    // The value/s can optionally be executed if it's a function
    access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
        var exec,
            bulk = key == null,
            i = 0,
            length = elems.length;

        // Sets many values
        if ( key && typeof key === "object" ) {
            for ( i in key ) {
                jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
            }
            chainable = 1;

        // Sets one value
        } else if ( value !== undefined ) {
            // Optionally, function values get executed if exec is true
            exec = pass === undefined && jQuery.isFunction( value );

            if ( bulk ) {
                // Bulk operations only iterate when executing function values
                if ( exec ) {
                    exec = fn;
                    fn = function( elem, key, value ) {
                        return exec.call( jQuery( elem ), value );
                    };

                // Otherwise they run against the entire set
                } else {
                    fn.call( elems, value );
                    fn = null;
                }
            }

            if ( fn ) {
                for (; i < length; i++ ) {
                    fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
                }
            }

            chainable = 1;
        }

        return chainable ?
            elems :

            // Gets
            bulk ?
                fn.call( elems ) :
                length ? fn( elems[0], key ) : emptyGet;
    },

     ...............................

});
原文地址:https://www.cnblogs.com/gongshunkai/p/5905917.html