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;
},
...............................
});