很多前端开发者在初学阶段,经常搞不清楚 prop() 和 attr() 到底什么时候用。我自己当年也踩过这个坑,尤其是处理复选框的选中状态时,用错方法导致结果总是不对。这篇文章就围绕 prop() 方法,把它的用途、语法、参数和容易混淆的地方讲透彻。
prop() 的两大核心用途
简单来说,prop() 在 jQuery 里主要做两件事:
-
读取属性值 — 获取匹配元素中第一个元素的指定 DOM 属性值。
-
设置属性值 — 为匹配元素设置一个或多个 DOM 属性值。
这里说的“属性”特指 DOM property,不是 HTML 标签上写的 attribute。很多初学者会忽略这个区别,后面会专门对比讲解。
为什么 prop() 更偏底层
当浏览器解析 HTML 时,会把标签上的 attributes 转成 DOM 对象的 properties。比如一个复选框:
<input type="checkbox" checked="checked">
这个 checked="checked" 是 HTML attribute,初始值就是固定的字符串。但在 DOM 对象上对应的 checked 属性是一个布尔值,会随着用户操作动态变化。你用 prop('checked') 拿到的是实时的 true 或 false,而 attr('checked') 拿到的是初始状态。
我个人经验是:只要涉及用户交互后的状态变更,一律用 prop(),attr() 只适合读取那些不会变的静态 HTML 属性。
四种语法形式
1. 读取属性
$(selector).prop(property)
返回匹配集中第一个元素的属性值。如果在空上调用,返回 undefined。
2. 设置单个属性
$(selector).prop(property, value)
为所有匹配元素统一设置某个 DOM 属性的值。
3. 使用回调函数设置
$(selector).prop(property, function(index, currentValue) {
return newValue;
})
函数接收两个参数:index 是元素在中的索引位置,currentValue 是该元素当前的属性值。这样可以根据每个元素的不同状态动态计算新值。
4. 批量设置多个属性
$(selector).prop({
property1: value1,
property2: value2,
...
})
对象写法,一次性配置多项属性,代码更简洁。
参数说明一览
| 参数 | 说明 |
|---|---|
| property | DOM 属性名,比如 "checked"、"disabled"、"selected"、"readOnly" 等 |
| value | 要设置的属性值,类型根据具体属性而定(布尔、字符串、数字等) |
| function(index, currentValue) | 回调函数,返回值将作为新值赋给属性 |
| index | 当前元素在 jQuery 对象中的位置索引,从 0 开始 |
| currentValue | 该元素当前 DOM 属性值 |
实战示例:自定义属性与 removeProp()
下面这个例子展示如何给 div 元素添加一个自定义 DOM 属性,读写它,然后用 removeProp() 删除。
$(document).ready(function(){
$("button").click(function(){
var $x = $("div");
// 设置自定义属性并读取
$x.prop("color", "#e0eeee");
$x.append("color 属性当前值:" + $x.prop("color"));
// 删除该属性
$x.removeProp("color");
$x.append("<br>删除后 color 属性值:" + $x.prop("color"));
});
});
这里展示的 color 是一个自定义的 DOM 属性,和 CSS 样式没有直接关系。项目开发中更常见的应用场景是给元素挂载自定义状态标记,比如 dataProcessed、isAnimating 等。
本节课程知识要点:removeProp() 一旦执行,该属性会彻底从 DOM 对象上移除,再次读取会得到 undefined,而不是回退到某个默认值。要小心不要删掉原生属性(如 checked、className 等),否则可能导致预期外行为。
常用场景:复选框状态检测
再来看一个和实际工作贴合度很高的例子——监听复选框变化并用不同方法读取状态:
<input id="check1" type="checkbox" checked="checked">
<label for="check1">勾选我试试</label>
<p></p>
$("input").change(function() {
var $input = $(this);
$("p").html(
".attr('checked'): <b>" + $input.attr("checked") + "</b><br>" +
".prop('checked'): <b>" + $input.prop("checked") + "</b><br>" +
".is(':checked'): <b>" + $input.is(":checked") + "</b>"
);
}).change();
运行后你会发现,无论怎么点击复选框,attr('checked') 始终显示 "checked" 字符串,而 prop('checked') 和 is(':checked') 会随着勾选/取消切换 true/false。这说明动态状态必须走 DOM property 路线。
prop() 与 attr() 的本质区别
很多人面试也老被问到这个问题,其实记住三点就够了:
-
attr() 操作的是 HTML 标签上写的 attribute,这些值在页面加载时确定,除非你再次用代码修改 attribute。
-
prop() 操作的是 DOM 元素的 property,反映元素对象的实时状态。
-
对布尔类型的 HTML 属性(如
checked、disabled、selected、readonly),强烈建议用 prop(),因为 DOM property 返回的是布尔值,逻辑判断更直观。
我个人代码里现在几乎不在交互逻辑中用 attr() 取状态了,只用它来获取或修改类似 href、title、data-* 这类比较“静态”的 attribute。
jQuery 虽然在新项目中用得少了,但大量存量项目依然离不开它。prop() 这个方法看起来简单,却恰恰是理解 DOM 工作机制的一个很好切入点。搞清楚了 attribute 和 property 的区别,对后续理解原生 JavaScript 的 getAttribute()、setAttribute() 和直接操作对象属性也很有帮助。