compare attr & prop

在高版本的 JQuery 引入 prop()方法后一直没有把它和 attr()做过多的区别,经常是用 attr()处理问题,少有时候用 prop(),由于前期的学习及结果的正确
性而没有过多的去关心理解这两者的区别;在最近的一次开发中遇到了类似 bug,由此在什么时候该用 attr()?什么时候该用 prop()?

  • .attr(),它从 jQuery1.0 就已经存在,官方文档说的是读写 dom 的 attribute 值;
  • .prop(),它在 jquery1.6 才引入,官方文档说的是读写 property 值;

其实 attr()和 prop()都是获取和设置指定的属性,均表示”属性”的意思;但在 JQuery 中 attribute 和 property 是两个不同的概念,attribute 表示 HTML 文档节点的属性,property 表示 js 对象的属性。如下:

1
2
3
4
5
6
7
<!-- 这里的id、classtypechecked均是该元素文档节点的attribute -->
<input id="content-test" class="content-test" type="checkbox" checked></div>

<script>
// 这里的name、color、address均是obj的property
var testObj = { name: "test", color: "red", address: "china" };
</script>
  • 那么在 jquery 底层实现中 attr()和 prop()都是通过什么实现的呢,其实它们都是通过 JS 原生的 element 对象实现的,其主要依赖的函数是 element 对象的 getAttribute()和 setAttribute()两个方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<input id="content-test" class="content-test" type="checkbox" checked="checked"></div>
<script>
var content = document.getElementById("content-test");
var $content = $(content);

// 相当于 content.setAttribute("checked", 'checked');
$content.attr("checked", "checked"); // 设置checked="checked"

// 相当于 content.getAttribute("checked");
var checkStage = $content.attr("checked"); // "checked"

/** prop()依赖的是JS原生的 element[property] 和 element[property] = value; **/

// 相当于 content["checked"] = "checked值";
$content.prop("checked", "checked值"); // 设置checked值到checked属性

// 相当于 content["pid"];
var checkStage = $content.prop("checked"); // checked值 —— true
</script>

当然,我们在 jquery 中使用的这些方法被封装之后使我们操作起来更方便,并跨浏览器兼容。

  • 上面了解到了两者的实现方式,它们最终的区别最终是什么呢?如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<input id="content-test1" class="content-test1" type="checkbox" checked="checked"></div>
<input id="content-test2" class="content-test2" type="checkbox" checked></div>
<input id="content-test3" class="content-test3" type="checkbox"></div>

<script>
var $content1 = $("#content-test1");
var $content2 = $("#content-test2");
var $content3 = $("#content-test3");

// 获取第一个input的checked状态值
$content1.attr("checked"); // 得到结果是得字符串值checked
$content1.prop("checked"); // 得到结果是布尔值true

// 获取第二个input的checked状态值
$content2.attr("checked"); // 得到结果是字符串值checked
$content2.prop("checked"); // 得到结果是布尔值true

// 获取第三个input的checked状态值
$content3.attr("checked"); // 得到结果是undefined
$content3.prop("checked"); // 得到结果是布尔值false
</script>

通过结果比对发现,在使用 attr()和 prop()得到的结果在 input 上没有 checked 选中状态时才会有所不同,结果表明 prop()会得到对应的布尔值,attr()
在没有将属性值没有正确的写成字符串时会得到 undefined。(在 checked = “ “的情况下 attr 和 prop 也都会得到正确的值,所以用的时候注意了)。

  • 讨论了半天,发现在使用 attr()和 prop()都能够正确的得到我们所想的情况,那究竟该如何使用这两个方法呢,根据官方文档所示,在 dom 结构中如果是其固有属性,即在 W3C 标准里就含有的属性,在处理时使用 prop() ———— 例如:class,id,checked 等;我们自定义的属性在处理时使用 attr() ———— 例如:action=”test”;最后上一个官方建议使用的 attr()和 prop()的情况表(下图来源网络):

  • 上述都是自己的学习理解,不足之处,请多多指正。。。