前文 對屬性的設(shè)置、讀取、刪除方法做了分解,本文繼續(xù)對jQuery attributes模塊分解。
?
jQuery.fn.addClass
/*
***********************************
* value: 字符串或者是函數(shù),字符串可以通過空格分隔className
*/
jQuery.fn.addClass
=
function
( value ) {
var
classes, elem, cur, clazz, j,
i
= 0
,
len
=
this
.length,
proceed
=
typeof
value === "string" &&
value;
//
如果value是函數(shù)
if
( jQuery.isFunction( value ) ) {
//
則對所有元素迭代運行addClass
return
this
.each(
function
( j ) {
jQuery(
this
).addClass( value.call(
this
, j,
this
.className ) );
});
}
//
如果value是字符串
if
( proceed ) {
//
對value字符串分割成數(shù)組
classes = ( value || "" ).match( core_rnotwhite ) ||
[];
//
遍歷元素
for
( ; i < len; i++
) {
elem
=
this
[ i ];
//
如果節(jié)點是元素,則獲取原來的className
cur = elem.nodeType === 1 && ( elem.className ?
(
" " + elem.className + " " ).replace( rclass, " " ) :
//
替換掉換行符制表符等
" "
);
//
如果cur不為false,即節(jié)點是元素
if
( cur ) {
j
= 0
;
//
遍歷classes組裝成新的className應(yīng)有的值
while
( (clazz = classes[j++
]) ) {
if
( cur.indexOf( " " + clazz + " " ) < 0
) {
cur
+= clazz + " "
;
}
}
//
對className賦值,去掉頭尾空白
elem.className =
jQuery.trim( cur );
}
}
}
return
this
;
};
添加class的實現(xiàn)上還是比較簡單的,利用elem.className來賦值。需要注意:
var rclass = /[\t\r\n]/g;
?
jQuery.fn.removeClass
jQuery.fn.removeClass =
function
( value ) {
var
classes, elem, cur, clazz, j,
i
= 0
,
len
=
this
.length,
//
參數(shù)是否正確
proceed = arguments.length === 0 ||
typeof
value === "string" &&
value;
//
如果value是函數(shù)
if
( jQuery.isFunction( value ) ) {
//
則對所有元素迭代運行removeClass
return
this
.each(
function
( j ) {
jQuery(
this
).removeClass( value.call(
this
, j,
this
.className ) );
});
}
//
如果參數(shù)正確
if
( proceed ) {
//
分隔value成為class字符串?dāng)?shù)組
classes = ( value || "" ).match( core_rnotwhite ) ||
[];
//
遍歷
for
( ; i < len; i++
) {
elem
=
this
[ i ];
//
獲取className并進(jìn)行預(yù)處理
cur = elem.nodeType === 1 && ( elem.className ?
(
" " + elem.className + " " ).replace( rclass, " "
) :
""
);
//
如果是元素
if
( cur ) {
j
= 0
;
//
遍歷所有class字符串
while
( (clazz = classes[j++
]) ) {
//
尋找是否有對應(yīng)的字符串
while
( cur.indexOf( " " + clazz + " " ) >= 0
) {
//
有則去掉
cur = cur.replace( " " + clazz + " ", " "
);
}
}
//
給className賦值,并去掉頭尾空格
elem.className = value ? jQuery.trim( cur ) : ""
;
}
}
}
return
this
;
};
刪除class的實現(xiàn)和addClass非常像,只是通過indexOf和replace來替換掉需要刪除的class。
?
jQuery.fn.toggleClass
jQuery.fn.toggleClass =
function
( value, stateVal ) {
var
type =
typeof
value,
isBool
=
typeof
stateVal === "boolean"
;
//
(⊙o⊙)…不說了,大家懂得
if
( jQuery.isFunction( value ) ) {
return
this
.each(
function
( i ) {
jQuery(
this
).toggleClass( value.call(
this
, i,
this
.className, stateVal), stateVal );
});
}
//
遍歷所有元素
return
this
.each(
function
() {
//
如果value是字符串
if
( type === "string"
) {
var
className,
i
= 0
,
self
= jQuery(
this
),
state
=
stateVal,
//
將value轉(zhuǎn)成classNames字符串?dāng)?shù)組
classNames = value.match( core_rnotwhite ) ||
[];
//
遍歷
while
( (className = classNames[ i++
]) ) {
//
stateVal是布爾量,則直接設(shè)置為stateVal,否則判斷元素是否不存在該className
state = isBool ? state : !
self.hasClass( className );
//
如果該className不存在則添加,否則刪除
self[ state ? "addClass" : "removeClass"
]( className );
}
//
如果value的類型是undefined或者boolean
}
else
if
( type === "undefined" || type === "boolean"
) {
//
如果元素的className存在
if
(
this
.className ) {
//
將其存入緩存
jQuery._data(
this
, "__className__",
this
.className );
}
//
對className賦值,為空或者緩存中的值
this
.className =
this
.className || value ===
false
? "" : jQuery._data(
this
, "__className__" ) || ""
;
}
});
};
為了實現(xiàn)jQuery.fn.toggleClass還是花了很大功夫的。
緩存的利用使得toggleClass操作更加方便,而不需要記錄以前是那些class。
?
jQuery.fn.hasClass
jQuery.fn.hasClass =
function
( selector ) {
var
className = " " + selector + " "
,
i
= 0
,
l
=
this
.length;
for
( ; i < l; i++
) {
if
(
this
[i].nodeType === 1 && (" " +
this
[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0
) {
return
true
;
}
}
return
false
;
};
這個函數(shù)通過indexOf來尋找className是否存在。
?
jQuery.fn.val
jQuery.fn.val =
function
( value ) {
var
hooks, ret, isFunction,
elem
=
this
[0
];
//
如果沒有參數(shù)
if
( !
arguments.length ) {
//
如果元素存在
if
( elem ) {
//
得到相應(yīng)的鉤子
hooks = jQuery.valHooks[ elem.type ] ||
jQuery.valHooks[ elem.nodeName.toLowerCase() ];
//
通過鉤子來得到值
if
( hooks && "get"
in
hooks && (ret = hooks.get( elem, "value" )) !==
undefined ) {
return
ret;
}
//
如果沒得到鉤子,則通過elem.value來返回值
ret =
elem.value;
//
如果ret是字符串
return
typeof
ret === "string" ?
//
將回車符替換
ret.replace(rreturn, ""
) :
//
如果ret是空的,則返回"",否則返回ret
ret ==
null
? ""
: ret;
}
return
;
}
//
value是否是函數(shù)
isFunction =
jQuery.isFunction( value );
//
遍歷所有元素
return
this
.each(
function
( i ) {
var
val,
self
= jQuery(
this
);
if
(
this
.nodeType !== 1
) {
return
;
}
//
如果value是函數(shù),則轉(zhuǎn)成參數(shù)
if
( isFunction ) {
val
= value.call(
this
, i, self.val() );
}
else
{
val
=
value;
}
//
將null/undefined當(dāng)成""
if
( val ==
null
) {
val
= ""
;
//
將數(shù)字轉(zhuǎn)成字符串
}
else
if
(
typeof
val === "number"
) {
val
+= ""
;
//
如果是數(shù)組,則遍歷數(shù)組
}
else
if
( jQuery.isArray( val ) ) {
val
= jQuery.map(val,
function
( value ) {
return
value ==
null
? "" : value + ""
;
});
}
//
獲取相應(yīng)鉤子
hooks = jQuery.valHooks[
this
.type ] || jQuery.valHooks[
this
.nodeName.toLowerCase() ];
//
如果鉤子無法設(shè)置,則使用通常的設(shè)置方法
if
( !hooks || !("set"
in
hooks) || hooks.set(
this
, val, "value" ) ===
undefined ) {
this
.value =
val;
}
});
};
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

