jQuery attributes提供了文檔節(jié)點的屬性操作方法。
為了更好的理解,我們先解決jQuery core中的access參數(shù)設置函數(shù)。
?
jQuery.access
jQuery.access是一個專用于參數(shù)設置以及讀取的方法。
在 jQuery鏈式操作 中我們對BigInteger的值獲取是通過方法val來獲取的,很顯然此時val后面不能再鏈式操作了。所以:
如果要讀取參數(shù)值,那么這個操作就不能鏈式操作。
/*
************************
* elems: 接受操作的元素組
* fn: 設置或讀取函數(shù)
* key: 要設置的屬性
* value: 要設置的值,也可以是函數(shù)
* chainable: 是否可以鏈式操作,即是讀還是寫操作
* emptyGet: 讀取如果為空用什么表示
* raw: value能否直接傳給fn,如果的確就是想將屬性設置成函數(shù)value,那么要把這個值設成true
*/
jQuery.access
=
function
( elems, fn, key, value, chainable, emptyGet, raw ) {
var
i = 0
,
length
=
elems.length,
//
key是否為空
bulk = key ==
null
;
//
設置許多屬性
if
( jQuery.type( key ) === "object"
) {
chainable
=
true
;
for
( i
in
key ) {
//
迭代執(zhí)行設置一個值
jQuery.access( elems, fn, i, key[i],
true
, emptyGet, raw );
}
//
只設置一個值
}
else
if
( value !==
undefined ) {
chainable
=
true
;
//
如果value不是函數(shù)
if
( !
jQuery.isFunction( value ) ) {
raw
=
true
;
}
//
如果key為空
if
( bulk ) {
//
如果raw為true,即value不是函數(shù)
if
( raw ) {
//
執(zhí)行fn,其this為elems,參數(shù)為value
fn.call( elems, value );
fn
=
null
;
//
如果value是函數(shù)
}
else
{
//
用bulk保存fn
bulk =
fn;
//
將fn變成特定形式
fn =
function
( elem, key, value ) {
return
bulk.call( jQuery( elem ), value );
};
}
}
//
如果fn存在
if
( fn ) {
//
遍歷所有elems
for
( ; i < length; i++
) {
//
value是函數(shù)則運行fn(elem, key, value.call(elem, i, fn(elem, key)))
//
value非函數(shù)則運行fn(elem, key, value)
fn( elems[i], key, raw ?
value : value.call( elems[i], i, fn( elems[i], key ) ) );
}
}
}
//
如果是可鏈式操作的則返回elems
return
chainable ?
elems :
//
否則則是讀取操作
bulk ?
fn.call( elems ) :
//
否則如果長度不為0,則返回fn( elems[0], key ),否則返回空
length ? fn( elems[0
], key ) : emptyGet;
}
jQuery官方文檔沒有該函數(shù),應該說這是jQuery的一個內(nèi)部工具。主要是為了實現(xiàn)jQuery中設置與讀取復用性邏輯以及其內(nèi)循環(huán)的,也就是為了節(jié)省寫代碼而已。
?
jQuery.fn.attr()
fn也就是jQuery實例對象的方法集。
fn中的方法attr也就是我們常用的attr方法。
如獲取em標簽的title屬性:
var
title = $("em").attr("title");
那么這個函數(shù)式怎么實現(xiàn)的呢?
jQuery.fn.attr =
function
( name, value ) {
return
jQuery.access(
this
, jQuery.attr, name, value, arguments.length > 1
);
};
當參數(shù)長度為0或只為1時,則是讀取操作,不能鏈式操作。
而這里用的設置函數(shù)是jQuery.attr,即實際運行時會運行jQuery.attr(elem, name, value)。
那么jQuery.attr是如何實現(xiàn)的呢?
/*
**************************
* elem: 要操作的元素
* name: 元素的屬性名
* value: 要改變的值
*/
jQuery.attr
=
function
( elem, name, value ) {
var
ret, hooks, notxml,
nType
=
elem.nodeType;
//
不處理text,comment,attribute節(jié)點
if
( !elem || nType === 3 || nType === 8 || nType === 2
) {
return
;
}
//
如果屬性不支持則使用jQuery.prop
if
(
typeof
elem.getAttribute === "undefined"
) {
return
jQuery.prop( elem, name, value );
}
//
是否不是XML
notxml = nType !== 1 || !
jQuery.isXMLDoc( elem );
//
如果不是XML
if
( notxml ) {
//
那么所有屬性名應當是小寫
name =
name.toLowerCase();
//
如果屬性定義了,那么就抓住必要的鉤子,解決IE6-9的相關(guān)問題
hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ?
boolHook : nodeHook );
}
//
如果value不是沒有定義,即寫入操作
if
( value !==
undefined ) {
//
如果value為空,則是刪除操作
if
( value ===
null
) {
jQuery.removeAttr( elem, name );
//
如果鉤子有set方法,則設置了之后,返回其值
}
else
if
( hooks && notxml && "set"
in
hooks && (ret = hooks.set( elem, value, name )) !==
undefined ) {
return
ret;
//
否則使用setAttribute方法
}
else
{
elem.setAttribute( name, value
+ ""
);
return
value;
}
//
如果是讀取操作,如果鉤子有g(shù)et方法,則通過get得到返回值
}
else
if
( hooks && notxml && "get"
in
hooks && (ret = hooks.get( elem, name )) !==
null
) {
return
ret;
//
如果沒有g(shù)et方法
}
else
{
//
IE9+中Flash對象沒有.getAttrubute方法,判斷防止錯誤
if
(
typeof
elem.getAttribute !== "undefined"
) {
ret
=
elem.getAttribute( name );
}
//
返回undefined或則值
return
ret ==
null
?
undefined :
ret;
}
};
?
jQuery.removeAttr
removeAttr =
function
( elem, value ) {
var
name, propName,
i
= 0
,
//
分解value成為多個屬性的數(shù)組
attrNames = value &&
value.match( core_rnotwhite );
//
如果有要刪除的屬性名
if
( attrNames && elem.nodeType === 1
) {
//
遍歷所有屬性名
while
( (name = attrNames[i++
]) ) {
//
看看需不需要用propFix來修改名字,不用直接用name
propName = jQuery.propFix[ name ] ||
name;
//
如果屬性是布爾量先改成false
if
( rboolean.test( name ) ) {
elem[ propName ]
=
false
;
}
//
刪除屬性
elem.removeAttribute( name );
}
}
};
jQuery.propFix干了什么呢?
實際只是修改一下屬性名,比如很多人喜歡用class來表示css類名,但實際上是className。
jQuery.propFix = {
tabindex:
"tabIndex"
,
readonly:
"readOnly"
,
"for": "htmlFor"
,
"class": "className"
,
maxlength:
"maxLength"
,
cellspacing:
"cellSpacing"
,
cellpadding:
"cellPadding"
,
rowspan:
"rowSpan"
,
colspan:
"colSpan"
,
usemap:
"useMap"
,
frameborder:
"frameBorder"
,
contenteditable:
"contentEditable"
};
?
jQuery.fn.removeAttr
這個函數(shù)實現(xiàn)比較簡單,只是用each方法來調(diào)用jQuery.removeAttr而已。
jQuery.fn.removeAttr =
function
( name ) {
return
this
.each(
function
() {
jQuery.removeAttr(
this
, name );
});
};
?
jQuery.fn.prop
jQuery.fn.prop =
function
( name, value ) {
return
jQuery.access(
this
, jQuery.prop, name, value, arguments.length > 1
);
};
可見jQuery.fn.prop和jQuery.fn.attr差不多。
?
jQuery.prop
jQuery.prop =
function
( elem, name, value ) {
var
ret, hooks, notxml,
nType
=
elem.nodeType;
if
( !elem || nType === 3 || nType === 8 || nType === 2
) {
return
;
}
notxml
= nType !== 1 || !
jQuery.isXMLDoc( elem );
if
( notxml ) {
//
修復name和鉤子
name = jQuery.propFix[ name ] ||
name;
hooks
=
jQuery.propHooks[ name ];
}
if
( value !==
undefined ) {
if
( hooks && "set"
in
hooks && (ret = hooks.set( elem, value, name )) !==
undefined ) {
return
ret;
}
else
{
return
( elem[ name ] =
value );
}
}
else
{
if
( hooks && "get"
in
hooks && (ret = hooks.get( elem, name )) !==
null
) {
return
ret;
}
else
{
return
elem[ name ];
}
}
};
由于和jQuery.attr差不多,就不備注了。
?
jQuery.fn.removeProp
removeProp =
function
( name ) {
name
= jQuery.propFix[ name ] ||
name;
return
this
.each(
function
() {
//
try/catch handles cases where IE balks (such as removing a property on window)
try
{
this
[ name ] =
undefined;
delete
this
[ name ];
}
catch
( e ) {}
});
};
removeProp相對簡單些,只是通過each將所有元素的屬性設為undefined然后delete掉而已。
?
Attrubute和Property
從源代碼我們可以發(fā)現(xiàn),jQuery.attr如果找不到相應的方法會使用jQuery.prop。
jQuery 1.6加入jQuery.prop方法后,對很多人來說可能根本沒啥用,因為用jQuery.attr方法肯定是對的。
但jQuery.attr和jQuery.prop到底差別在哪里呢?
這是Attrubute和Property的差別。
jQuery.attr方法會處理Attrubute和Property,但jQuery.prop只處理Property。
雖然這兩個單詞都可以翻譯成“屬性”,但是這兩個實際上是不同的。
我們用一個例子來說明這個問題:
function
Demo(){
var
attrs =
{};
this
.name = "Bob"
;
this
.setAttr =
function
(name, value){
attrs[name]
=
value;
return
value;
}
this
.getAttr =
function
(name){
return
attrs[name];
}
}
那么對于一個實例:
var
i =
new
Demo();
i.name
//
Property
i.setAttr("name", "Tom"
);
i.getAttr(
"name")
//
Attrubute
所以jQuery文檔中對jQuery.prop的解釋是: 獲取在匹配的元素集中的第一個元素的屬性值。
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

