標籤:
這一課,我們將講解val方法,以及對value屬性的相容性處理,jQuery中通過valHooks對象來處理。
首先,我們先來看下val方法的使用:
$("#input1").val() //擷取input元素的value屬性值
$("#input1").val("hello") //設定input元素的value屬性值為hello。
然後我們來看一下val方法的源碼:
jQuery.fn.extend({
......
val: function( value ) {
var hooks, ret, isFunction,
elem = this[0];
if ( !arguments.length ) { //如果是擷取操作,也就是參數為0時.
if ( elem ) {
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
//valHooks有以下幾個屬性對象:option(下拉框的子選項),select(下拉框),radio(選項按鈕),checkbox(複選按鈕)。也就意味著需要對這四種元素進行相容性處理。其中radio的type=radio,checkbox的type=checkbox,select的type,預設為select-one(單選),還可以設定成select-multiple(<select multiple><option></option></select>,多選)。
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
return ret;
}
ret = elem.value;
return typeof ret === "string" ? ret.replace(rreturn, "") : ret == null ? "" : ret;
}
return;
}
isFunction = jQuery.isFunction( value );
return this.each(function( i ) { //設定作業,是針對每個元素
var val;
if ( this.nodeType !== 1 ) { //必須是元素節點
return;
}
if ( isFunction ) {
val = value.call( this, i, jQuery( this ).val() );
} else {
val = value;
}
if ( val == null ) { //針對這種情況:$("input").val(null);
val = "";
} else if ( typeof val === "number" ) { //如果傳入的是數字類型,就轉換成字串
val += "";
} else if ( jQuery.isArray( val ) ) { //這裡是針對checkbox,radio這種元素的,比如:$("#input2").val(["hello"]);這裡如果傳入的是字串的話,是對checkbox的value屬性賦值,但是傳入數組,就代表checkbox的value是否等於hello,如果等於,就被選擇上,如果不等於就不被選擇上。
val = jQuery.map(val, function ( value ) {
return value == null ? "" : value + "";
});
}
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { //請看下面的代碼解釋
this.value = val;
}
});
}
});
jQuery.extend({
valHooks: {
option: { //當你擷取option元素的value屬性值時,如果沒有對此option顯式設定value值,擷取到的值是option的text,也就是option的文本。但是IE6-7下擷取到的值是""。
get: function( elem ) {
var val = elem.attributes.value; //在IE6-7下,val是一個object。
return val.specified ? elem.value : elem.text;//如果val.specified為true,就代表value被顯式設定了,因此直接返回elem.value,如果為false,就代表沒有顯式設定,因此返回elem.text。
}
},
select: {
get: function( elem ) { //當select是單選時,擷取的value值,就是你選擇的那個option的值,如果是多選,擷取值時,就是你選擇的所有option的值的數組形式。
var value, option,
options = elem.options, //select的所有option的集合。
index = elem.selectedIndex, //當前選擇的option的索引值
one = elem.type === "select-one" || index < 0,
values = one ? null : [], //如果是單選,values=null,如果是多選,values=[]。
max = one ? index + 1 : options.length,
i = index < 0 ? max : one ? index : 0;
for ( ; i < max; i++ ) { //單選,迴圈一次,多選,迴圈多次
option = options[ i ];
if ( ( option.selected || i === index ) && //IE6-9下,點擊reset按鈕時,option的selected不會恢複預設值,其他瀏覽器會恢複所有option的selected的預設值。
( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && //如果option被設定了disabled,那麼擷取option的值時,是擷取不到的。
( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { //如果option的父元素被設定了disabled,並且父元素是optgroup,那麼也擷取不到。
value = jQuery( option ).val();
if ( one ) {
return value;
}
values.push( value );
}
}
return values;
},
set: function( elem, value ) {
var optionSet, option,
options = elem.options,
values = jQuery.makeArray( value ), //把value轉換成數組
i = options.length;
while ( i-- ) {
option = options[ i ];
if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { //判斷select的子項目option的value是否在values數組中,如果在,就會把這個option選中。
optionSet = true;
}
}
if ( !optionSet ) {
elem.selectedIndex = -1; //如果select下的option的value值沒有一個等於value的,那麼就讓select的選擇索引值賦為-1.讓select框中沒有任何值。
}
return values;
}
}
}
})
jQuery.each([ "radio", "checkbox" ], function() {
jQuery.valHooks[ this ] = {
set: function( elem, value ) {
if ( jQuery.isArray( value ) ) { //當value是數組時,看此元素的value值是否在數組value中,如果在就讓元素被選擇上。此元素只有radio,checkbox這兩種。
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
}
}
};
if ( !jQuery.support.checkOn ) { //如果元素是radio或者checkbox,我們去擷取它的預設value值時,老版本webkit得到的值是"",而其他瀏覽器是on,因此當沒有對此元素顯式設定它的value值時(通過getAttribute擷取的value的是null),我們通過input.value擷取它的預設值,所有瀏覽器都返回on。
jQuery.valHooks[ this ].get = function( elem ) {
return elem.getAttribute("value") === null ? "on" : elem.value;
};
}
});
相容處理,在jQuery中叫做hooks。針對不同的相容處理,有不同的hooks來處理。比如:value值,就有valHooks,屬性值,就有attrHooks,propHooks等。
加油!
jquery源碼解析:jQuery對元素屬性的操作3