JS中attr和prop属性的区别以及优先选择示例介绍


Posted in Javascript onJune 30, 2014

相比attr,prop是1.6.1才新出来的,两者从中文意思理解,都是获取/设置属性的方法(attributes和properties)。只是,window或document中使用.attr()方法在jQuery1.6之前不能正常运行,因为window和document中不能有attributes。prop应运而生了。

既然我们想知道他们两的区别,最好就看看他们的源代码,不要被代码长度所吓到,我们只看关键的几句:

attr: function( elem, name, value, pass ) { 
var ret, hooks, notxml, 
nType = elem.nodeType; 
// don't get/set attributes on text, comment and attribute nodes 
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 
return; 
} 
if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { 
return jQuery( elem )[ name ]( value ); 
} 
// Fallback to prop when attributes are not supported 
if ( typeof elem.getAttribute === "undefined" ) { 
return jQuery.prop( elem, name, value ); 
} 
notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 
// All attributes are lowercase 
// Grab necessary hook if one is defined 
if ( notxml ) { 
name = name.toLowerCase(); 
hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); 
} 
if ( value !== undefined ) { 
if ( value === null ) { 
jQuery.removeAttr( elem, name ); 
return; 
} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { 
return ret; 
} else { 
elem.setAttribute( name, value + "" ); 
return value; 
} 
} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { 
return ret; 
} else { 
ret = elem.getAttribute( name ); 
// Non-existent attributes return null, we normalize to undefined 
return ret === null ? 
undefined : 
ret; 
} 
}

prop方法代码(jQuery版本1.8.3)

prop: function( elem, name, value ) { 
var ret, hooks, notxml, 
nType = elem.nodeType; 
// don't get/set properties on text, comment and attribute nodes 
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 
return; 
} 
notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 
if ( notxml ) { 
// 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; 
} else { 
return ( elem[ name ] = value ); 
} 
} else { 
if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { 
return ret; 
} else { 
return elem[ name ]; 
} 
} 
}

attr方法里面,最关键的两行代码,elem.setAttribute( name, value + “” )和ret = elem.getAttribute( name ),很明显的看出来,使用的DOM的API setAttribute和getAttribute方法操作的属性元素节点。
而prop方法里面,最关键的两行代码,return ( elem[ name ] = value )和return elem[ name ],你可以理解成这样document.getElementById(el)[name] = value,这是转化成JS对象的一个属性。

既然明白了原理是这样,我们来看看一个例子:

<input type="checkbox" id="test" abc="111" />
$(function(){ 
el = $("#test"); 
console.log(el.attr("style")); //undefined 
console.log(el.prop("style")); //CSSStyleDeclaration对象 
console.log(document.getElementById("test").style); //CSSStyleDeclaration对象 
});

el.attr(“style”)输出undefined,因为attr是获取的这个对象属性节点的值,很显然此时没有这个属性节点,自然输出undefined
el.prop(“style”)输出CSSStyleDeclaration对象,对于一个DOM对象,是具有原生的style对象属性的,所以输出了style对象
至于document.getElementById(“test”).style和上面那条一样

接着看:

el.attr("abc","111") 
console.log(el.attr("abc")); //111 
console.log(el.prop("abc")); //undefined

首先用attr方法给这个对象添加abc节点属性,值为111,可以看到html的结构也变了

el.attr(“abc”)输出结果为111,再正常不过了
el.prop(“abc”)输出undefined,因为abc是在这个的属性节点中,所以通过prop是取不到的

el.prop("abc", "222"); 
console.log(el.attr("abc")); //111 
console.log(el.prop("abc")); //222

我们再用prop方法给这个对象设置了abc属性,值为222,可以看到html的结构是没有变化的。输出的结果就不解释了。

上面已经把原理讲清楚了,什么时候用什么就可以自己把握了。

提一下,在遇到要获取或设置checked,selected,readonly和disabled等属性时,用prop方法显然更好,比如像下面这样:

<input type="checkbox" id="test" checked="checked" />
console.log(el.attr("checked")); //checked 
console.log(el.prop("checked")); //true 
console.log(el.attr("disabled")); //undefined 
console.log(el.prop("disabled")); //false

显然,布尔值比字符串值让接下来的处理更合理。

PS一下,如果你有JS性能洁癖的话,显然prop的性能更高,因为attr需要访问DOM属性节点,访问DOM是最耗时的。这种情况适用于多选项全选和反选的情况。

大家都知道有的浏览器只要写disabled,checked就可以了,而有的要写成disabled = "disabled",checked="checked",比如用attr("checked")获取checkbox的checked属性时选中的时候可以取到值,值为"checked"但没选中获取值就是undefined。

jq提供新的方法“prop”来获取这些属性,就是来解决这个问题的,以前我们使用attr获取checked属性时返回"checked"和"",现在使用prop方法获取属性则统一返回true和false。

那么,什么时候使用attr(),什么时候使用prop()?
1.添加属性名称该属性就会生效应该使用prop();
2.是有true,false两个属性使用prop();
3.其他则使用attr();
项目中jquery升级的时候大家要注意这点!

以下是官方建议attr(),prop()的使用:

以下是官方建议attr(),prop()的使用:

JS中attr和prop属性的区别以及优先选择示例介绍

Javascript 相关文章推荐
jquery获取input表单值的代码
Apr 19 Javascript
理解Javascript_11_constructor实现原理
Oct 18 Javascript
javascript对数组的常用操作代码 数组方法总汇
Jan 27 Javascript
MooBox 基于Mootools的对话框插件
Jan 20 Javascript
深入浅析同源策略和跨域访问
Nov 26 Javascript
EasyUI中在表单提交之前进行验证
Jul 19 Javascript
Bootstrap CSS组件之导航条(navbar)
Dec 17 Javascript
webpack中CommonsChunkPlugin详细教程(小结)
Nov 09 Javascript
Vue2(三)实现子菜单展开收缩,带动画效果实现方法
Apr 28 Javascript
vue中使用props传值的方法
May 08 Javascript
uni-app之APP和小程序微信授权方法
May 09 Javascript
JavaScript变量基本使用方法实例分析
Nov 15 Javascript
Visual Studio中js调试的方法图解
Jun 30 #Javascript
ff chrome和ie下全局动态定位的异同及全局高度的取法
Jun 30 #Javascript
js从Cookies里面取值的简单实现
Jun 30 #Javascript
jQuery学习总结之jQuery事件
Jun 30 #Javascript
JavaScript 获取任一float型小数点后两位的小数
Jun 30 #Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
Jun 30 #Javascript
jquery实现人性化的有选择性禁用鼠标右键
Jun 30 #Javascript
You might like
php中去除所有js,html,css代码
2010/10/12 PHP
PHP中函数rand和mt_rand的区别比较
2012/12/26 PHP
php打开文件fopen函数的使用说明
2013/07/05 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
ThinkPHP3.2.2的插件控制器功能简述
2014/07/09 PHP
PHP实现图片上传并压缩
2015/12/22 PHP
PHP实现压缩图片尺寸并转为jpg格式的方法示例
2018/05/10 PHP
Yii框架安装简明教程
2020/05/15 PHP
Javascript操纵Cookie实现购物车程序
2007/02/15 Javascript
使用户点击后退按钮使效三行代码
2007/07/07 Javascript
javascript新手语法小结
2008/06/15 Javascript
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
2012/01/15 Javascript
JavaScript定时器详解及实例
2013/08/01 Javascript
jQuery中使用each处理json数据
2015/04/23 Javascript
nodejs连接mysql数据库简单封装示例-mysql模块
2017/04/10 NodeJs
JavaScript 数组的进化与性能分析
2017/09/18 Javascript
使用vue2.0创建的项目的步骤方法
2018/09/25 Javascript
jQuery实现的记住帐号密码功能完整示例
2019/08/03 jQuery
在Vue里如何把网页的数据导出到Excel的方法
2020/09/30 Javascript
wxPython学习之主框架实例
2014/09/28 Python
详细探究Python中的字典容器
2015/04/14 Python
Python的Django框架中设置日期和字段可选的方法
2015/07/17 Python
一份python入门应该看的学习资料
2018/04/11 Python
python write无法写入文件的解决方法
2019/01/23 Python
基于Django的乐观锁与悲观锁解决订单并发问题详解
2019/07/31 Python
利用Python实现kNN算法的代码
2019/08/16 Python
PYTHON绘制雷达图代码实例
2019/10/15 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
2019/12/04 Python
基于python生成英文版词云图代码实例
2020/05/16 Python
让IE6、IE7、IE8支持CSS3的脚本
2010/07/20 HTML / CSS
中学生社区服务活动报告
2015/02/05 职场文书
水电工岗位职责
2015/02/14 职场文书
小组组名及励志口号
2015/12/24 职场文书
确保减税降费落地生根,用实实在在措施
2019/07/19 职场文书
理解python中装饰器的作用
2021/07/21 Python
一级电子管军用接收机测评
2022/04/05 无线电