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面向对象编程
Mar 02 Javascript
JavaScript.The.Good.Parts阅读笔记(一)假值与===运算符
Nov 16 Javascript
js实时监听文本框状态的方法
Apr 26 Javascript
使用Jquery来实现可以输入值的下拉选单 雏型
Dec 06 Javascript
jQuery插件开发精品教程让你的jQuery提升一个台阶
Jan 27 Javascript
浅谈angular2 组件的生命周期钩子
Aug 12 Javascript
vue.js将时间戳转化为日期格式的实现代码
Jun 05 Javascript
AngularJS中ng-options实现下拉列表的数据绑定方法
Aug 13 Javascript
js对象数组和对象的使用实例详解
Aug 27 Javascript
微信小程序实现发微博功能的示例代码
Jun 24 Javascript
vue中解决微信html5原生ios虚拟键返回不刷新问题
Oct 20 Javascript
vue的hash值原理也是table切换实例代码
Dec 14 Vue.js
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
Linux下PHP连接Oracle数据库
2014/08/20 PHP
PHP获取数组最后一个值的2种方法
2015/01/21 PHP
php上传图片客户端和服务器端实现方法
2015/03/30 PHP
用PHP代码在网页上生成图片
2015/07/01 PHP
ThinkPHP 5 AJAX跨域请求头设置实现过程解析
2020/10/28 PHP
jQuery 扩展对input的一些操作方法
2009/10/30 Javascript
30个精美的jQuery幻灯片效果插件和教程
2011/08/23 Javascript
js设置cookie过期及清除浏览器对应名称的cookie
2013/10/24 Javascript
js 高效去除数组重复元素示例代码
2013/12/19 Javascript
javascript浏览器兼容教程之事件处理
2014/06/09 Javascript
javascript实现带下拉子菜单的导航菜单效果
2015/05/14 Javascript
jqueryMobile使用示例分享
2016/01/12 Javascript
AngularJS单选框及多选框实现双向动态绑定
2016/01/13 Javascript
剖析Node.js异步编程中的回调与代码设计模式
2016/02/16 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
2016/08/18 Javascript
解析ajaxFileUpload 异步上传文件简单使用
2016/12/30 Javascript
整理关于Bootstrap导航的慕课笔记
2017/03/29 Javascript
jQuery实现拖动效果的实例代码
2017/06/25 jQuery
利用Vconsole和Fillder进行移动端抓包调试方法
2019/03/05 Javascript
JS 自执行函数原理及用法
2019/08/05 Javascript
layui+SSM的数据表的增删改实例(利用弹框添加、修改)
2019/09/27 Javascript
node.js使用http模块创建服务器和客户端完整示例
2020/02/10 Javascript
[02:16]卖萌的僵尸 DOTA2神话信使飞僵小宝来袭
2014/03/24 DOTA
python访问抓取网页常用命令总结
2017/04/11 Python
分享一个可以生成各种进制格式IP的小工具实例代码
2017/07/28 Python
Python中的 sort 和 sorted的用法与区别
2019/08/10 Python
Django为窗体加上防机器人的验证码功能过程解析
2019/08/14 Python
Numpy 多维数据数组的实现
2020/06/18 Python
HTML5仿手机微信聊天界面
2016/03/18 HTML / CSS
面试后感谢信
2014/02/01 职场文书
生日礼品店创业计划书范文
2014/03/21 职场文书
社区护士演讲稿
2014/08/27 职场文书
学习心理学的体会
2014/11/07 职场文书
社区党风廉政建设调研报告
2015/01/01 职场文书
教师考核表个人总结
2015/02/12 职场文书
2015年施工员工作总结范文
2015/04/20 职场文书