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 相关文章推荐
javascript vvorld 在线加密破解方法
Nov 13 Javascript
改进版通过Json对象实现深复制的方法
Oct 24 Javascript
关于JavaScript的面向对象和继承有利新手学习
Jan 11 Javascript
js获得网页背景色和字体色的方法
Mar 21 Javascript
JavaScript实现为input与textarea自定义hover,focus效果的方法
Aug 21 Javascript
jquery mobile 移动web(5)
Dec 20 Javascript
vue实现简单表格组件实例详解
Apr 16 Javascript
VUE中使用Vue-resource完成交互
Jul 21 Javascript
vue中实现滚动加载更多的示例
Nov 08 Javascript
webpack打包多页面的方法
Nov 30 Javascript
Element-UI+Vue模式使用总结
Jan 02 Javascript
基于原生js实现判断元素是否有指定class名
Jul 11 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
DC四月将推出百页特刊漫画 纪念小丑诞生80周年
2020/04/09 欧美动漫
PHP+JS+rsa数据加密传输实现代码
2011/03/23 PHP
PHP中变量引用与变量销毁机制分析
2014/11/15 PHP
php中 $$str 中 &quot;$$&quot; 的详解
2015/07/06 PHP
基于Jquery的温度计动画效果
2010/06/18 Javascript
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
2011/09/20 Javascript
基于jQuery实现图片的前进与后退功能
2013/04/24 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
2013/12/06 Javascript
jquery的ajax异步请求接收返回json数据实例
2014/06/16 Javascript
Nodejs学习笔记之入门篇
2015/04/16 NodeJs
JS提交form表单实例分析
2015/12/10 Javascript
jquery将标签元素的高设为屏幕的百分比
2017/04/19 jQuery
详解Vue单元测试case写法
2018/05/24 Javascript
VUE 3D轮播图封装实现方法
2018/07/03 Javascript
构建一个JavaScript插件系统
2020/10/20 Javascript
Python中的异常处理学习笔记
2015/01/28 Python
Python中多线程的创建及基本调用方法
2016/07/08 Python
请不要重复犯我在学习Python和Linux系统上的错误
2016/12/12 Python
tensorflow TFRecords文件的生成和读取的方法
2018/02/06 Python
python消除序列的重复值并保持顺序不变的实例
2018/11/08 Python
如何使用Python标准库进行性能测试
2019/06/25 Python
对python3中的RE(正则表达式)-详细总结
2019/07/23 Python
详解Python文件修改的两种方式
2019/08/22 Python
在tensorflow中实现去除不足一个batch的数据
2020/01/20 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
2020/06/10 Python
详解如何在pyqt中通过OpenCV实现对窗口的透视变换
2020/09/20 Python
安全的后院和健身蹦床:JumpSport
2019/07/15 全球购物
美国高端牛仔品牌:Silver Jeans
2019/12/12 全球购物
五一促销活动总结
2014/07/01 职场文书
创先争优活动承诺书
2014/08/30 职场文书
好人好事演讲稿
2014/09/01 职场文书
领导班子“四风问题”“整改方案
2014/10/02 职场文书
2014年党的群众路线学习心得体会
2014/11/05 职场文书
2015年药品销售工作总结范文
2015/05/25 职场文书
建议书的格式及范文
2015/09/14 职场文书
opencv 分类白天与夜景视频的方法
2021/06/05 Python