jQuery中 prop 与 attr 方法的区别
前言
attr() 方法是在jQuery 1.0版本就存在的一个获取DOM元素借点上attributes的方法。从jQuery 1.6版本开始,添加了一个porp()方法,改方法用于设置或返回当前jQuery对象所匹配的元素的属性值。
在jQuery中,"attribute" 和"property"却是两个不同的概念。attribute表示HTML文档节点的属性,property表示JS对象的属性
浅析一下 jQuery-V3.1.1 源码
attr()方法部分源码
attr: function( elem, name, value ) {
var ret, hooks,
nType = elem.nodeType;
// Don't get/set attributes on text, comment and attribute nodes
if ( nType === 3 || nType === 8 || nType === 2 ) {
return;
}
// Fallback to prop when attributes are not supported
if ( typeof elem.getAttribute === "undefined" ) {
return jQuery.prop( elem, name, value );
}
// Attribute hooks are determined by the lowercase version
// Grab necessary hook if one is defined
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
}
if ( value !== undefined ) {
if ( value === null ) {
jQuery.removeAttr( elem, name );
return;
}
if ( hooks && "set" in hooks &&
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
return ret;
}
elem.setAttribute( name, value + "" );
return value;
}
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
return ret;
}
ret = jQuery.find.attr( elem, name );
// Non-existent attributes return null, we normalize to undefined
return ret == null ? undefined : ret;
}
prop()方法部分源码
prop: function( elem, name, value ) {
var ret, hooks,
nType = elem.nodeType;
// Don't get/set properties on text, comment and attribute nodes
if ( nType === 3 || nType === 8 || nType === 2 ) {
return;
}
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
// Fix name and attach hooks
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;
}
return ( elem[ name ] = value );
}
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
return ret;
}
return elem[ name ];
}
具体区别有哪些?
方法各自操作的对象不同
attr()方法操作的是DOM节点。我们可以从源码可以看出来, attr() 会利用 element 的 getAttribute() 方法去获取值。
prop()方法操作的是DOM对象。prop() 跟 attr() 方法稍微有所不同,prop() 方法会直接从当前调用的jQuery对象中进行取值。很显然prop的性能更高,因为attr需要访问DOM属性节点,访问DOM是最耗时的。这种情况适用于多选项全选和反选的情况。
值类型不同
attr()方法只能设置字符串类型的属性值,如果传递的值非字符串类型,也会调用toString()转换成字符串类型。
prop()方法操作的是JS对象的属性,因此设置的属性值可以为包括数组和对象在内的任意类型
什么时候该用prop?什么时候用attr?
- 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法。
- 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法。
使用案例
HTML模板
<div class="box">
<label><input class="check_ipt_01" type="checkbox" checked="checked" />我是一个傲娇的复选框</label>
<label><input class="check_ipt_02" type="checkbox" />我是的复选框老二</label>
</div>
attr()方法案例
<script type="text/javascript">
$(function() {
// 获取属性值
console.info($('.box').attr('class')); // box
// 设置自定义属性,值类型为字符串
$('.box').attr('cus_attr', 'custom value');
console.info($('.box').attr('cus_attr')); // custom value
// 设置自定义属性,值类型为非字符串
$('.box').attr('cus_attr', [1, 2, 3, 4]);
console.info($('.box').attr('cus_attr')); // 1,2,3,4
// 获取复选框的值
console.info($('.check_ipt_01').attr('checked')); // checked
console.info($('.check_ipt_02').attr('checked')); // undefined
});
</script>
prop()方法案例
$(function() {
// 获取属性值
console.info($('.box').prop('class')); // box
// 设置自定义属性,值类型为字符串
$('.box').prop('cus_attr', 'custom value');
console.info($('.box').prop('cus_attr')); // custom value
// 设置自定义属性,值类型为非字符串
$('.box').prop('cus_attr', [1, 2, 3, 4]);
console.info($('.box').prop('cus_attr')); // [1, 2, 3, 4]
// 获取复选框的值
console.info($('.check_ipt_01').prop('checked')); // true
console.info($('.check_ipt_02').prop('checked')); // false
});
注意
从1.6开始,使用attr()获取这些属性的返回值为String类型,如果被选中(或禁用)就返回checked、selected或disabled,否则(即元素节点没有该属性)返回undefined。并且,在某些版本中,这些属性值表示文档加载时的初始状态值,即使之后更改了这些元素的选中(或禁用)状态,对应的属性值也不会发生改变。