提问人:Naftali 提问时间:5/4/2011 最后编辑:Naftali 更新时间:8/16/2023 访问量:721893
.prop() 与 .attr()
.prop() vs .attr()
问:
所以 jQuery 1.6 有新的函数 prop()。
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
或者在这种情况下,他们会做同样的事情吗?
如果我必须切换到使用 ,如果我切换到 1.6,所有旧调用都会中断?prop()
attr()
更新
selector = '#id'
$(selector).click(function() {
//instead of:
var getAtt = this.getAttribute('style');
//do i use:
var thisProp = $(this).prop('style');
//or:
var thisAttr = $(this).attr('style');
console.log(getAtt, thisProp, thisAttr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id='id' style="color: red;background: orange;">test</div>
(另见这把小提琴:http://jsfiddle.net/maniator/JpUF2/)
控制台将 记录为字符串,并将 记录为字符串,但 作为 , 为什么?这对我未来的编码有什么影响?getAttribute
attr
prop
CSSStyleDeclaration
答:
一切都在文档中:
在特定情况下,属性和属性之间的差异可能很重要。在 jQuery 1.6 之前,.attr() 方法在检索某些属性时有时会考虑属性值,这可能会导致行为不一致。从 jQuery 1.6 开始,.prop() 方法提供了一种显式检索属性值的方法,而 .attr() 检索属性。
所以使用道具!
对于jQuery来说,这种变化已经有很长一段时间了。多年来,他们一直满足于一个名为函数的函数,该函数主要检索 DOM 属性,而不是您期望从名称中获得的结果。attr(
) 和 prop()
的分离应该有助于缓解 HTML 属性和 DOM 属性之间的一些混淆。 抓取指定的 DOM 属性,同时抓取指定的 HTML 属性。attr()
$.fn.prop()
$.fn.attr()
为了充分理解它们的工作原理,以下是对 HTML 属性和 DOM 属性之间差异的扩展说明。
HTML 属性
语法:
<body onload="foo()">
目的:允许标记具有与其关联的数据,用于事件、呈现和其他目的。
可视化: class 属性显示在正文上。可通过以下代码访问它:
var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");
属性以字符串形式返回,并且可能因浏览器而异。但是,在某些情况下,它们可能至关重要。如上所述,IE 8 Quirks 模式(及更低版本)需要 get/set/removeAttribute 中的 DOM 属性名称,而不是属性名称。这是了解差异很重要的众多原因之一。
DOM 属性
语法:
document.body.onload = foo;
目的:授予对属于元素节点的属性的访问。这些属性类似于特性,但只能通过 JavaScript 访问。这是一个重要的区别,有助于阐明 DOM 属性的作用。请注意,属性与属性完全不同,因为此事件处理程序赋值是无用的,并且不会接收事件(body 没有 onload 事件,只有 onload 属性)。
可视化:
在这里,您会注意到 Firebug 中“DOM”选项卡下的属性列表。这些是 DOM 属性。您会立即注意到其中的很多,因为您以前在不知不觉中使用过它们。它们的值是您将通过 JavaScript 接收的值。
文档
例
HTML格式:<textarea id="test" value="foo"></textarea>
JavaScript的:alert($('#test').attr('value'));
在早期版本的 jQuery 中,这将返回一个空字符串。在 1.6 中,它返回正确的值 .foo
在不看任何一个函数的新代码的情况下,我可以自信地说,这种混淆更多地与 HTML 属性和 DOM 属性之间的差异有关,而不是与代码本身有关。希望这能为您清除一些事情。
-马 特
评论
$.prop()
获取 DOM 属性,获取 HTML 属性。我试图在心理上弥合差距,这样你就可以理解两者之间的区别。$.attr()
$('#test').prop('value')
.attr('checked')
prop('checked')
更新日期:2012 年 11 月 1 日
我最初的答案特别适用于 jQuery 1.6。我的建议保持不变,但 jQuery 1.6.1 略有改变:面对预测的一堆损坏的网站,jQuery 团队将 attr
() 恢复到接近(但不完全相同)其布尔属性的旧行为。约翰·雷西格(John Resig)也在博客上写了这篇文章。我能看出他们所处的困难,但仍然不同意他的建议。attr()
原始答案
如果您只使用过 jQuery 而不是直接使用 DOM,这可能是一个令人困惑的更改,尽管它在概念上绝对是一个改进。对于使用jQuery的无数网站来说,这并不是那么好,这些网站会因为这种变化而中断。
我将总结主要问题:
- 你通常想要而不是.
prop()
attr()
- 在大多数情况下,做以前做的事情。在代码中替换对 with 的调用通常有效。
prop()
attr()
attr()
prop()
- 属性通常比属性更易于处理。属性值只能是字符串,而属性可以是任何类型。例如,属性是布尔值,属性是具有每种样式的单独属性的对象,属性是一个数字。
checked
style
size
- 如果属性和属性都存在相同的名称,通常更新一个属性将更新另一个属性,但对于输入的某些属性,例如 and: 对于这些属性,属性始终表示当前状态,而属性(旧版本的 IE 除外)对应于输入的默认值/检查性(反映在 / 属性中)。
value
checked
defaultValue
defaultChecked
- 此更改删除了卡在属性和属性前面的一些魔术 jQuery 层,这意味着 jQuery 开发人员将不得不了解属性和属性之间的区别。这是一件好事。
如果你是一个jQuery开发人员,并且对整个业务的属性和属性感到困惑,你需要退后一步,了解一下它,因为jQuery不再那么努力地保护你免受这些东西的影响。对于这个主题的权威但有些枯燥的词,有规范:DOM4、HTML DOM、DOM Level 2、DOM Level 3。 Mozilla 的 DOM 文档对大多数现代浏览器都有效,并且比规范更容易阅读,因此您可能会发现他们的 DOM 参考很有帮助。有一节是关于元素属性的。
作为属性如何比属性更易于处理的示例,请考虑最初选中的复选框。以下是两个可能的有效 HTML 片段来执行此操作:
<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">
那么,如何确定该复选框是否被jQuery选中呢?查看 Stack Overflow,您通常会找到以下建议:
if ( $("#cb").attr("checked") === true ) {...}
if ( $("#cb").attr("checked") == "checked" ) {...}
if ( $("#cb").is(":checked") ) {...}
这实际上是世界上最简单的 Boolean 属性,自 1995 年以来,它一直存在于每个主要的可编写脚本的浏览器中并完美运行:checked
if (document.getElementById("cb").checked) {...}
该属性还使选中或取消选中复选框变得微不足道:
document.getElementById("cb").checked = false
在 jQuery 1.6 中,这明确地变成了
$("#cb").prop("checked", false)
使用该属性编写复选框脚本的想法是无用且不必要的。该物业是您所需要的。checked
- 使用属性检查或取消选中复选框的正确方法尚不清楚
checked
- 属性值反映的是默认值,而不是当前的可见状态(除了某些旧版本的 IE,因此使事情变得更加困难)。该属性不会告诉您页面上的复选框是否被选中。请参见 http://jsfiddle.net/VktA6/49/。
评论
value
我认为 Tim 说得很好,但让我们退后一步:
DOM 元素是一个对象,是内存中的事物。与 OOP 中的大多数对象一样,它具有属性。此外,它还具有在元素上定义的属性的映射(通常来自浏览器读取以创建元素的标记)。元素的某些属性从具有相同或相似名称的属性中获取其初始值(从“value”属性中获取其初始值; 从“href”属性中获取其初始值,但它不完全相同的值; 从“class”属性)。其他属性通过其他方式获取其初始值:例如,属性根据其父元素获取其值;元素始终具有属性,无论它是否具有“style”属性。value
href
className
parentNode
style
让我们在以下页面中考虑这个锚点:http://example.com/testing.html
<a href="foo.html" class="test one" name="fooAnchor" id="fooAnchor">Hi</a>
一些无缘无故的 ASCII 艺术(并遗漏了很多东西):
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | HTMLAnchorElement | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | href: "http://example.com/foo.html" | | name: "fooAnchor" | | id: "fooAnchor" | | className: "test one" | | attributes: +−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | | href: "foo.html" | | | | name: "fooAnchor" | | | | id: "fooAnchor" | | | | class: "test one" | | | +−−−−−−−−−−−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
请注意,属性和特性是不同的。
现在,尽管它们是不同的,但由于所有这些都是演变的,而不是从头开始设计的,因此,如果您设置它们,许多属性会写回它们派生的属性。但并非所有人都这样做,正如你从上面看到的,映射并不总是直接的“传递价值”,有时涉及解释。href
当我说属性是对象的属性时,我不是抽象地说的。下面是一些非 jQuery 代码:
const link = document.getElementById("fooAnchor");
console.log(link.href); // Shows "http://example.com/foo.html"
console.log(link.getAttribute("href")); // Shows "foo.html"
对象是一个真实的东西,你可以看到访问它的属性和访问属性之间有真正的区别。link
正如 Tim 所说,绝大多数时候,我们都希望与物业合作。部分原因是它们的值(甚至它们的名称)在浏览器之间往往更加一致。我们大多只想在没有与之相关的属性(自定义属性)时才使用属性,或者当我们知道对于该特定属性,属性和属性不是 1:1(如上面的 “href”)。href
标准属性在各种 DOM 规范中列出:
这些规范有很好的索引,我建议把它们的链接放在手边;我一直在使用它们。
例如,自定义属性将包括您可能在元素上放置的任何属性,以便为代码提供元数据(现在,只要您坚持使用前缀,它就从 HTML5 开始有效)。(最新版本的jQuery允许你通过函数访问元素,但该函数不仅仅是属性的访问器[它的作用既多又少];除非你真的需要它的功能,否则我会使用这个函数与属性进行交互。data-xyz
data-
data-xyz
data
data-xyz
attr
data-xyz
该函数过去有一些复杂的逻辑来获取他们认为您想要的东西,而不是从字面上获取属性。它混淆了这些概念。搬到并旨在将它们分开。简而言之,在 v1.6.0 中,jQuery 在这方面走得太远了,但功能很快就被添加回去,以处理人们在技术上应该使用 .attr
prop
attr
attr
attr
prop
只是 HTML 属性和 DOM 对象之间的区别导致了混淆。对于那些喜欢在DOM元素上执行本机属性(如等)的人来说,这是一个非常热烈的欢迎家庭。对于其他人来说,这只是一层额外的混乱。让我们弄清楚这一点。this.src
this.value
this.checked
.prop
查看 and 之间差异的最简单方法是以下示例:.attr
.prop
<input blah="hello">
- $('input')
.attr('blah'):
按预期返回。这里没有假设。'hello'
- $('input')
.prop('blah'):
返回 -- 因为它正在尝试这样做 -- 并且该 DOM 对象上不存在这样的属性。它仅作为该元素的属性存在于作用域中,即undefined
[HTMLInputElement].blah
[HTMLInputElement].getAttribute('blah')
现在我们更改一些内容,如下所示:
$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
- $('input')
.attr('blah'):
返回嗯?为什么不是“梨”,因为这是在该元素上最后设置的。因为属性是在输入属性上更改的,而不是 DOM 输入元素本身,所以它们基本上几乎彼此独立工作。'apple'
- $('input')
.prop('blah'):
返回'pear'
由于上述原因,您真正需要注意的是,不要在整个应用程序中将这些用于同一属性。
请看一把小提琴,展示其中的区别:http://jsfiddle.net/garreh/uLQXc/
.attr
与:.prop
第 1 轮:风格
<input style="font:arial;"/>
.attr('style')
-- 返回匹配元素的内联样式,即"font:arial;"
.prop('style')
-- 返回一个样式声明对象,即CSSStyleDeclaration
第 2 轮:价值
<input value="hello" type="text"/>
$('input').prop('value', 'i changed the value');
.attr('value')
--返回'hello'
*.prop('value')
--返回'i changed the value'
* 注意:jQuery为此有一个方法,在内部等价于.val()
.prop('value')
属性位于 DOM 中;属性位于解析为 DOM 的 HTML 中。
更多细节
如果更改属性,则更改将反映在 DOM 中(有时使用不同的名称)。
示例:更改标签的属性将更改 DOM 中该标签的属性(这是因为它是 JavaScript 中的保留字,不能用于属性名称)。
如果标记上没有属性,则仍具有具有空值或默认值的相应 DOM 属性。class
className
class
示例:虽然您的标记没有属性,但 DOM 属性确实存在,但字符串值为空。class
className
编辑
如果更改一个,则控制器将更改另一个,反之亦然。 此控制器不在 jQuery 中,而是在浏览器的本机代码中。
通常,您需要使用属性。 仅将属性用于:
- 获取自定义 HTML 属性(因为它未与 DOM 属性同步)。
- 获取与 DOM 属性不同步的 HTML 属性,例如获取标准 HTML 属性的“原始值”,例如
<input value="abc">.
肮脏的检查
此概念提供了一个可观察到差异的示例:http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty
试试看:
- 单击按钮。两个复选框都被选中了。
- 取消选中这两个复选框。
- 再次单击该按钮。只选中了复选框。砰!
prop
$('button').on('click', function() {
$('#attr').attr('checked', 'checked')
$('#prop').prop('checked', true)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>attr <input id="attr" type="checkbox"></label>
<label>prop <input id="prop" type="checkbox"></label>
<button type="button">Set checked attr and prop.</button>
对于某些属性(如 on),添加或删除 content 属性总是会切换该属性(在 HTML5 中称为 IDL 属性),因为 http://www.w3.org/TR/html5/forms.html#attr-fe-disabled 说:disabled
button
disabled="disabled"
禁用的 IDL 属性必须反映禁用的内容属性。
所以你可能会侥幸逃脱,尽管它很丑陋,因为它不需要修改 HTML。
对于其他属性,如 on ,事情会中断,因为一旦你单击它,它就会变脏,然后添加或删除 content 属性不会再切换 checkedness。checked="checked"
input type="checkbox"
checked="checked"
这就是为什么你应该主要使用 ,因为它直接影响有效属性,而不是依赖于修改 HTML 的复杂副作用。.prop
TL;博士
在大多数情况下使用。prop()
attr()
属性是输入元素的当前状态。属性是默认值。
属性可以包含不同类型的内容。属性只能包含字符串
评论
prop() and when to go for attr()
attributes
-> HTML
properties
-> DOM
评论
属性位于您的 HTML 文本文档/文件中(== 想象这是解析 HTML 标记的结果),而
属性位于 HTML DOM 树中(== 基本上是 JS 意义上某个对象的实际属性)。
重要的是,它们中的许多都是同步的(如果你更新属性,html中的属性也会更新;否则)。但是某些属性可能会同步到意外的属性 - 例如,属性对应于 property ,因此class
class
checked
defaultChecked
- 手动选中复选框将更改值,但不会更改值
.prop('checked')
.attr('checked')
.prop('defaultChecked')
- 设置也会改变,但这在元素上是不可见的。
$('#input').prop('defaultChecked', true)
.attr('checked')
经验法则是:方法应该用于布尔属性/属性和 html 中不存在的属性 (例如 window.location)。所有其他属性(您可以在 HTML) 可以而且应该继续使用该方法进行操作。(http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/
.prop()
.attr()
)
这里有一个表格,显示了首选的位置(即使仍然可以使用)。.prop()
.attr()
为什么你有时想使用 .prop() 而不是 .attr(),而后者是官方建议的?
.prop()
可以返回任何类型 - 字符串、整数、布尔值;while 始终返回一个字符串。.attr()
.prop()
据说比 快 2.5 倍左右。.attr()
Gary Hole 的答案与解决问题非常相关,如果代码以这种方式编写
obj.prop("style","border:1px red solid;")
由于 prop 函数返回对象,上述代码在某些浏览器中无法正常工作(在我的情况下进行了测试)。CSSStyleDeclaration
IE8 with Chrome Frame Plugin
因此将其更改为以下代码
obj.prop("style").cssText = "border:1px red solid;"
解决了问题。
轻轻提醒使用,示例:prop()
if ($("#checkbox1").prop('checked')) {
isDelete = 1;
} else {
isDelete = 0;
}
上面的函数用于检查checkbox1是否被选中,如果勾选:返回1;如果没有:返回 0。函数 prop() 在这里用作 GET 函数。
if ($("#checkbox1").prop('checked', true)) {
isDelete = 1;
} else {
isDelete = 0;
}
上面的函数用于设置要选中的 checkbox1 并始终返回 1。现在函数 prop() 用作 SET 函数。
不要搞砸。
P/S:当我检查图像 src 属性时。如果 src 为空,则 prop 返回页面的当前 URL(错误),attr 返回空字符串(右)。
在 jQuery 1.6 之前,该方法有时会在检索属性时考虑属性值,这会导致相当不一致的行为。attr()
该方法的引入提供了一种显式检索属性值的方法,同时检索属性。prop()
.attr()
文档:
jQuery.attr()
获取匹配元素集中第一个元素的属性值。
jQuery.prop()
获取匹配元素集中第一个元素的属性值。
.attr()
:
- 获取匹配元素集中第一个元素的属性值。
- 在页面加载时为您提供在 html 中定义的元素值
.prop()
:
- 获取匹配元素集中第一个元素的属性值。
- 给出通过javascript/jquery修改的元素的更新值
1) 属性在 DOM 中;属性位于 HTML 中,即 解析到 DOM 中。
2) $( elem ).attr( “checked” ) (1.6.1+) “checked” (String) 将 使用复选框状态进行更改
3) $( elem ).attr( “checked” ) (pre-1.6) true (Boolean) 已更改 具有复选框状态
大多数情况下,我们想用于 DOM 对象而不是自定义属性 喜欢。
data-img, data-xyz
在访问值时也有一些区别,并且 with 和 as thing 会随着 DOM 输出的变化而改变,并带有复选框的完整链接和值
checkbox
href
attr()
prop()
prop()
origin
Boolean
(pre-1.6)
我们只能使用其他元素访问 DOM 元素,然后它给出
undefined
prop
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>prop demo</title>
<style>
p {
margin: 20px 0 0;
}
b {
color: blue;
}
</style>
</head>
<body>
<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>
<script>
$("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();
</script>
</body>
</html>
有一件事可以做,但不能做:影响CSS选择器.attr()
.prop()
这是我在其他答案中没有看到的问题。
CSS 选择器[name=value]
- 将回应
.attr('name', 'value')
- 但并非总是如此
.prop('name', 'value')
.prop()
仅影响少数属性选择器
.attr()
影响所有属性选择器
input[value]
input[naame]
span[name]
input[data-custom-attribute]
(两者都不会影响此选择器).data('custom-attribute')
评论
attr
prop
get
prop() 与 attr() 相比,还有更多的注意事项:
selectedIndex、tagName、nodeName、nodeType、ownerDocument、defaultChecked 和 defaultSelected。etc 应该使用 .prop() 方法检索和设置。它们没有相应的属性,只是属性。
“对于输入类型”复选框
.attr('checked') //returns checked .prop('checked') //returns true .is(':checked') //returns true
prop 方法返回 checked、selected、disabled、 只读。.etc,而 attr 返回定义的字符串。所以,你可以直接 在 if 条件中使用 .prop('checked')。
.attr() 在内部调用 .prop(),因此 .attr() 方法会略微 比直接通过 .prop() 访问它们慢。
评论