jQuery access()方法解析

来源:互联网 发布:cat linux 指定行 编辑:程序博客网 时间:2024/05/29 10:32

研究jQuery源码的时候发现access这个方法使用范围很大,而且代码比较绕,在这里做一个总结

一、简介
access()是一个多功能方法,作为set和get值来使用,在jQuery中有以下方法对它进行了调用:attr(),prop(),text(),html(),css(),data(),scrollLeft(),scrollTop()

二、函数调用
我们在使用以上函数的时候,通常的使用方法有以下几种:
1.获取属性值/文本值

    $('xx').css('color');    $('xx').data('aaa');    $('xx').text();    $(document).scrollLeft();    $("input[type='checkbox']").prop("checked");

2.设置属性/文本值

    $("input[type='checkbox']").prop("checked", true);    $("xx").css("color","red");    $("xx").css({ "color": "red", "background": "blue" });    //还有一种特殊方式    <div class="aa" style="color:red;">123</div>    $('.aa').text(function(index,text){        return Number(text)+1;    });//div的值被修改为124

三、参数和调用
我们先来看看access的参数

/**    elems : 一个元素的集合    fn : 回调函数    key : 对应.css("color","red"); 中的color    value : 对应.css("color","red"); 中的value    chainable : get/set的标识,用来判断返回不同的内容    emptyGet : 暂时发现只会被当成undefined来做判断调用    raw : 用来判断value是否为函数**/access: function( elems, fn, key, value, chainable, emptyGet, raw )

在css()中的调用方式:

css: function( name, value ) {        return jQuery.access( this, function( elem, name, value ) {            var styles, len,                map = {},                i = 0;            if ( jQuery.isArray( name ) ) {                styles = getStyles( elem );                len = name.length;                for ( ; i < len; i++ ) {                    map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );                }                return map;            }            return value !== undefined ?                jQuery.style( elem, name, value ) :                jQuery.css( elem, name );        }, name, value, arguments.length > 1 );    }

在text()中的调用方式(注意key值):

text: function( value ) {        return jQuery.access( this, function( value ) {            return value === undefined ?                jQuery.text( this ) :                this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );        }, null, value, arguments.length );    }

在这里为了方便判断jQuery在text()、html()这种以文本操作和css()、prop()、data()等这种以属性操作的函数中做了一个区分:text()和html()的key参数被设置为null
接下来看看具体的代码

四、access方法具体解析

    access: function( elems, fn, key, value, chainable, emptyGet, raw ) {            var i = 0, //设置了一个循环起点                length = elems.length, //获取元素的长度对多个元素进行操作                bulk = key == null; //在这里判断是否为文本操作方法(text、html)会做不同的处理            // Sets many values            //如果参数以{key:value,key:value}的形式传进来会对这个对象进行遍历,然后递归引用access方法进行设置            if ( jQuery.type( key ) === "object" ) {                chainable = true; //标识操作为set                for ( i in key ) {                    jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );                }                // Sets one value                //此处判断文本操作(text(),html())设置字符串或者传入的是函数做处理            } else if ( value !== undefined ) {                chainable = true; //标识操作为set                if ( !jQuery.isFunction( value ) ) {                    raw = true;                }                if ( bulk ) {                    // Bulk operations run against the entire set                    //如果value为文本在这里直接使用回调函数进行处理后下文不再做处理                    if ( raw ) {                        fn.call( elems, value );                        fn = null;                        // ...except when executing function values                        //如果value为函数会在这里针对性的包装后在下边的if进行处理                    } else {                        bulk = fn;                        fn = function( elem, key, value ) {                            return bulk.call( jQuery( elem ), value );                        };                    }                }                //使用各函数的回调作为统一处理                if ( fn ) {                    for ( ; i < length; i++ ) {                        fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );                    }                }            }            //如果使用的是set功能则返回elems本身,否则为get功能此时:假如使用的是text(),html()方法则直接返回文本值,否则的话返回第一个元素的参数值。其他情况直接返回undefined(比如元素未找到)            return chainable ?                elems :                // Gets                bulk ?                    fn.call( elems ) :                    length ? fn( elems[0], key ) : emptyGet;        }

总结:函数走了两个方向,第一个方向是set:如果key存在并且为object时做了一个递归设置值的操作,如果key为null但是value有值的时候则是设置文本的操作(text(),html())此时做了一个细分,如果value为文本则直接使用上级的回调函数做处理(设置文本内容到html页面),如果value为函数,则使用函数处理后继续调用上级回调函数再次处理。
之后使用上级回调函数(包装回调函数)进行统一的处理

第二个方向get就是最后的return,此时如果走的是set返回了elems本身,如果走的是get则文本方法返回文本值,属性方法返回元素集合第一个属性的值,其他返回undefined