jQuery 解惑 - attr()、prop()、data()
jQuery 中提供了 3 个方法, .attr()
、 .prop()
和 .data()
,本文就介绍下这 3 者之间的不同。
.attr 和 .prop
关于这组概念在 jquery-1.6.1
的升级日志里说的太清楚不过了,看: 这里 ,这里我大体总结下。
其实有一句话非常关键,大家只要理解了它,就自然明白了:
property
是元素的固有特性,体现了它相关的 attribute
(如果存在的话)
比如:对于 checkbox
而言 checked
是其固有特性。怎么理解这句话呢?
看看示例:
<input type="checkbox">
- 这里没有 checked 这个属性(attribute),即:$('#checkbox').attr('checked') 的值是 undefined
- 但是我可以通过 js,获取其是否选中的特性,即:$('#checkbox').prop('checked') 的值是 false
- 原生 js 的写法是:document.getElementById('checkbox').checked //结果是:false
看看效果:
那么,为什么在 1.6.1 开始就区分了 attr
和 prop
这 2 个概念了呢?
以下阐述可能就是原因:
对于 document
和 window
这 2 个 js 对象,他们是没有 attributes
的(可以看到的属性),因为这是 2 个隐藏于页面内部的 2 个对象。
但是, window
却拥有类似于 loation
、 screen
等 properties
。明白了吧?
也就是说,直到 1.6.1 开始,人们才认清了属性和特性之间的区别,应该区分来处理。
看看示例:
什么时候用 prop
,什么时候用 attr
The .prop() method should be used for boolean attributes/properties and for properties which do not exist in html (such as window.location). All other attributes (ones you can see in the html) can and should continue to be manipulated with the .attr() method.
.prop()
是用在具有 Boolean
类型属性/特性上,而且对于特性而言它们并不在 html 上存在(比如:window.location),其它你能在页面上看到的所有的属性,都可以使用 .attr()
。
**说明:**在 jquery-1.6.1
之后,你也可以使用 .attr()
来获取 document/window
的一些特性,但是对于类似于 checked
之类的,如果页面上没有这个属性,你获取到的结果是 undefined
,并不能很好的反应其是否被选中!所以,该用 .prop()
的时候还是要用。
.attr 和 .data
从 jquery-1.4.3
开始支持 .data()
来获取元素上绑定的数据。
为什么 jQuery 要增加这个方法?因为 HTML5 新增了一种属性结果: data-*
HTML5 增加 data-*
属性的背景
比如,我们在 Bootstrap 中就可以随处看到这种直接在 html 上增加数据绑定,比如: popover
<button type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="top" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> Popover on top </button>
那么,HTML5 为什么要增加这种属性呢?
Before HTML5, working with arbitrary data sucked. To keep things valid, you had to stuff things into rel or class attributes. Some developers even created their own custom attributes. Boy, was it a mess.
But that all changed with the introduction of HTML5 custom data attributes. Now you can store arbitrary data in an easy, standards-compliant way.
在 HTML5 之前,开发者为了临时保存一些与标签有关的数据时,往往把数据临时保存到 rel
、 class
这些标签上,甚至有些人就自己造一些标签来保存,简直混乱不堪。
所有 HTML5 就增加了 data-*
的标签,以专门用来缓存标签数据。
.data()
有哪些特别之处
1、获取数据时不需要加前缀 data-
<a href="#" data-str="bar">foo!</a>
$('#foo').data('str'); //"bar"
而通过 .attr()
获取的话,需要携带上。
$('#foo').attr('data-str'); //"bar"
2、获取的数据会被自动转换格式
<a href="#" data-str="bar" data-bool="true" data-num="15" data-json='{"fizz":["buzz"]}'>foo!</a>
$('#foo').data('str'); //string "bar" $('#foo').data('bool'); //boolean true $('#foo').data('num'); //numuber 15 $('#foo').data('json'); //object {fizz:['buzz']}
而通过 .attr()
获取的数据,全部是 string
类型。
3、获取数据时可以使用 驼峰式
取值
data-*
的格式规定: data-
之后所有单词之间用中划线 -
,这样再取值的时候,js 可以直接用驼峰取值。
<input type="checkbox" data-name-width="1080" data-name_height="1920">
console.log($("#checkbox").attr('data-name-width'));//string "1080" console.log($("#checkbox").data('name-width'));//integer 1080 console.log($("#checkbox").data('nameWidth'));//integer 1080 console.log($("#checkbox").attr('data-name_height'));//string "1920" console.log($("#checkbox").data('name_height'));//integer 1920 console.log($("#checkbox").data('nameHeight'));//undefined
说明:
data-
之后当然也可以使用下划线_
,但是就不支持驼峰取值了;- 使用驼峰式,还可以这么取值:
$("#checkbox").data()['nameHeight']
,但是$("#checkbox").data()['name-height']
就获取不到值,可能的原因是:js 中不推荐使用中划线。
4、与 .prop()
有几分相似
我们通过上文知道 prop
是元素固有特性,体现了 attr
(如果存在的话)。意思就是, prop
可以不在 html 标签上出现,但其实它是存在的。
data
也是一样的!如果你体现到标签上,那么就可以通过 .attr()
获取,但是没有体现出来,就获取不到,只能通过 .data()
获取。
栗子:通过 js 动态给元素增加 data,这时候就只能通过 .data()
获取到,而通过 .attr()
是获取不到的。
//动态增加 data $("#checkbox").data('name-width2',222); //获取值 $("#checkbox").data('name-width2');//222 $("#checkbox").attr('data-name-width2');//undefined
反过来:通过 .attr()
修改了标签上 data 的值,通过 .data()
获取的值其实没变。
//修改值 $("#checkbox").attr('data-name-width',2000); //获取值 $("#checkbox").attr('data-name-width');//"2000" $("#checkbox").data('name-width');//1080,注意:这里是没有改变的。
所以,大家在使用 .attr()
和 .data()
时,一定不要混合使用,不然可能就会出错,也就是赋值和取值用同一种标签,就肯定没错。
其它说明
其实在 HTML5 中已经有 API 提供了类似于 jquery 的方法,就是 dataset
。
// Here's our button var button = document.getElementById('your-button-id'); // Get the values var cmd = button.dataset.cmd; var id = button.dataset.id; // Change the values button.dataset.cmd = yourNewCmd; button.dataset.id = yourNewId;
参考
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论