您的位置:首页 > Web前端 > JQuery

jQuery.access源码分析

2015-08-24 00:00 766 查看

基本理解

jQuery.attr是jQuery.attr,jQuery.prop,jQuery.css提供底层支持,jQuery里一个比较有特色的地方就是函数的重载, 比如attr,有如下几种重载

$('#box').attr('title')

$('#box').attr('title','标题')

$('#box').attr({title:'标题',data-menu-toggle:'dropdown'})

$('#box').attr('title',function () {....})

但是纵观jQuery.attr代码中,却没有判断value是不是存在啊之类的,ok,你猜对了,在access里实现了
jQuery.fn.extend({  attr: function (name, value) {    return jQuery.access(this, jQuery.attr, name, value, arguments.length > 1);  },  removeAttr: function (name) {    return this.each(function () {      jQuery.removeAttr(this, name);    });  },  prop: function (name, value) {    return jQuery.access(this, jQuery.prop, name, value, arguments.length > 1);  }
});


源码分析

大致思路

1.首先判断key值是不是一个object,如果是,遍历key,递归调用jQuery.access,并将是否可以链式调用的标志位设置为true

2.判断value值是否已经定义,如果已经定义,说明是个set操作

2.1 set操作的是可链式调用的

2.2 如果value不是function,设置raw为true

2.3 判断key值是否为null或者undefined,key若为空值

2.3.1 如果value不是个函数,或者强制赋值raw为true,那么调用fn,可能是以下调用:$('#box').attr(null,{abc:'def',a:'1'})

2.3.1 如果value是个函数,将fn包装之,改变原来fn的作用域和参数

2.4 如果fn存在,遍历jQuery内部元素,分别执行set操作

3.首先判断是否为set方法,如果是,返回 elems,如果不是执行get操作(如果jQuery内部length为0,返回指定的默认空值)

源码

// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
/**
attr: function (name, value) {
return jQuery.access(this, jQuery.attr, name, value, arguments.length > 1);
},
*
* @param elems jQuery的this
* @param fn 函数
* @param key 属性
* @param value 值
* @param chainable 是否可以链式调用,如果是get动作,为false,如果是set动作,为true
* @param emptyGet 如果jQuery没有选中到元素的返回值
* @param raw value是否为原始数据,如果raw是true,说明value是原始数据,如果是false,说明raw是个函数
* @returns {*}     */
access: function( elems, fn, key, value, chainable, emptyGet, raw ) {        var i = 0,
length = elems.length,
bulk = key == null; // bulk 体积,容量;大多数,大部分;大块

// Sets many values
/**
* 如果参数key是对象,表示要设置多个属性,则遍历参数key,遍历调用access方法
*
* $('#box').attr({data:1,def:'addd'});         */
if ( jQuery.type( key ) === "object" ) {
chainable = true; //表示可以链式调用
for ( i in key ) {
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
}        // Sets one value

/**
* $('#box').attr('customvalue','abc')
* $('#box').attr('customvalue',function (value) {});             */

} else if ( value !== undefined ) {
chainable = true;            if ( !jQuery.isFunction( value ) ) {
raw = true;
}            if ( bulk ) { // if (key == null && value !== undefined)
// Bulk operations run against the entire set
/**
* $('#box').attr(undefined,'abc')
*
* jQuery.attr.call(elems,value); 调用完毕之后,将fn设置为空                 */
if ( raw ) {
fn.call( elems, value );
fn = null;                // ...except when executing function values
/**
* $('#box').attr(undefined,function () {})
*
* fn = bulk = jQuery.attr;
*
* fn = function (elem, key, value) {
*  return jQuery.attr.call(jQuery(elem),value);
* }
*                     */
} else { //如果key有值的话,好办,这里的bulk是为了节省一个变量,将fn用bulk存起来,然后封装fn的调用
bulk = fn;
fn = function( elem, key, value ) {                        return bulk.call( jQuery( elem ), value );
};
}
}            //jQuery.access(elems,jQuery.attr,)

//如果fn存在,掉调用每一个元素,无论key是否有值,都会走到这个判断,执行set动作
if ( fn ) { // 递归调用之
for ( ; i < length; i++ ) {
fn( elems[i], key,
raw ? value :                        /**
* 如果value是原始数据,就取value,如果是个函数,就调用这个函数取值
* $('#box').attr('abc',function (index,value) { index指向当前元素的索引,value指向oldValue
*
*  先调用jQuery.attr(elements[i],key) 取到当前的值,然后调用传入的fn值
* });                         */

value.call( elems[i], i, fn( elems[i], key ) )
);
}
}
}        /**
* 如果chainable为true,说明是个set方法,就返回elems
* 否则说明是get方法
* 1.如果bulk是个true,说明没有key值,调用fn,将elems传进去
* 2.如果bulk为false,说明key有值哦,然后判断元素的长度是否大于0
*    2.1 如果大于0,调用fn,传入elems[0]和key,完成get
*    2.2 如果为0,说明传参有问题,返回指定的空值emptyGet         */
return chainable ?
elems :            // Gets
bulk ?
fn.call( elems ) :
length ? fn( elems[0], key ) : emptyGet;
},
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jquery