.prop() 与 .attr()

.prop() vs .attr()

提问人:Naftali 提问时间:5/4/2011 最后编辑:Naftali 更新时间:8/16/2023 访问量:721893

问:

所以 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/)

控制台将 记录为字符串,并将 记录为字符串,但 作为 , 为什么?这对我未来的编码有什么影响?getAttributeattrpropCSSStyleDeclaration

javascript jquery dom attr prop

评论

17赞 5/4/2011
这将引起人们的极大兴趣:books.google.ca/......
29赞 5/4/2011
@Neal,这是因为此更改超越了 jQuery。HTML 属性和 DOM 属性之间的差异是巨大的。
7赞 5/14/2011
看到jQuery恢复了更改,我很难过。他们正朝着错误的方向前进。
4赞 5/14/2011
@Neal。是的,它只是使问题进一步复杂化,而不是将两种方法分开。
6赞 Kevin B 1/4/2014
@BritishDeveloper答案比简单地说总是使用 x 或 y 要复杂得多,因为这取决于你打算得到什么。是想要属性,还是想要属性?它们是两个截然不同的东西。

答:

38赞 Arnaud F. 5/4/2011 #1

一切都在文档中

在特定情况下,属性和属性之间的差异可能很重要。在 jQuery 1.6 之前,.attr() 方法在检索某些属性时有时会考虑属性值,这可能会导致行为不一致。从 jQuery 1.6 开始,.prop() 方法提供了一种显式检索属性值的方法,而 .attr() 检索属性。

所以使用道具!

258赞 user1385191 5/4/2011 #2

对于jQuery来说,这种变化已经有很长一段时间了。多年来,他们一直满足于一个名为函数的函数,该函数主要检索 DOM 属性,而不是您期望从名称中获得的结果。attr() 和 prop() 的分离应该有助于缓解 HTML 属性和 DOM 属性之间的一些混淆。 抓取指定的 DOM 属性,同时抓取指定的 HTML 属性。attr()$.fn.prop()$.fn.attr()

为了充分理解它们的工作原理,以下是对 HTML 属性和 DOM 属性之间差异的扩展说明。

HTML 属性

语法:

<body onload="foo()">

目的:允许标记具有与其关联的数据,用于事件、呈现和其他目的。

可视化: HTML Attributes 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 属性)。

可视化: DOM Properties

在这里,您会注意到 Firebug 中“DOM”选项卡下的属性列表。这些是 DOM 属性。您会立即注意到其中的很多,因为您以前在不知不觉中使用过它们。它们的值是您将通过 JavaScript 接收的值。

文档

HTML格式:<textarea id="test" value="foo"></textarea>

JavaScript的:alert($('#test').attr('value'));

在早期版本的 jQuery 中,这将返回一个空字符串。在 1.6 中,它返回正确的值 .foo

在不看任何一个函数的新代码的情况下,我可以自信地说,这种混淆更多地与 HTML 属性和 DOM 属性之间的差异有关,而不是与代码本身有关。希望这能为您清除一些事情。

-马 特

评论

13赞 5/4/2011
$.prop()获取 DOM 属性,获取 HTML 属性。我试图在心理上弥合差距,这样你就可以理解两者之间的区别。$.attr()
12赞 BlueRaja - Danny Pflughoeft 5/4/2011
男孩,我现在也很困惑。所以不返回任何东西?复选框也没有?但过去是这样吗?现在你必须把它改成?我不明白这种区别的必要性 - 为什么区分 HTML 属性和 DOM 属性很重要?使这种变化“很长一段时间”的常见用例是什么?将两者之间的区别抽象出来有什么问题,因为它们的用例似乎大多重叠?$('#test').prop('value').attr('checked')prop('checked')
0赞 Kim Steinhaug 5/3/2022
为什么要区分 HTML 属性和 DOM 属性?当您在浏览器中加载网页时,HTML 会被解析为 DOM,用于可视化演示。假设您有一个未选中复选框的表单,然后您选中了它。如果您使用 $.attr(),则不会从 HTML 中检查哪个是正确的。但是,将检查 $.prop(),这也是正确的,因为我们检查了它。如果您需要使用源代码,或者像其他指出的初始值一样,请使用 $.attr() 否则使用 $.prop()。此外,在 Chrome 开发者工具中,元素将 DOM 显示为 html 而不是 HTML SOURCE。
1963赞 Tim Down 5/4/2011 #3

更新日期: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()
  • 属性通常比属性更易于处理。属性值只能是字符串,而属性可以是任何类型。例如,属性是布尔值,属性是具有每种样式的单独属性的对象,属性是一个数字。checkedstylesize
  • 如果属性和属性都存在相同的名称,通常更新一个属性将更新另一个属性,但对于输入的某些属性,例如 and: 对于这些属性,属性始终表示当前状态,而属性(旧版本的 IE 除外)对应于输入的默认值/检查性(反映在 / 属性中)。valuecheckeddefaultValuedefaultChecked
  • 此更改删除了卡在属性和属性前面的一些魔术 jQuery 层,这意味着 jQuery 开发人员将不得不了解属性和属性之间的区别。这是一件好事。

如果你是一个jQuery开发人员,并且对整个业务的属性和属性感到困惑,你需要退后一步,了解一下它,因为jQuery不再那么努力地保护你免受这些东西的影响。对于这个主题的权威但有些枯燥的词,有规范:DOM4HTML DOM、DOM Level 2、DOM Level 3Mozilla 的 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/

评论

61赞 T.J. Crowder 5/4/2011
@Neal:DOM 元素是一个对象。属性是该对象的属性,就像任何其他编程对象一样。其中一些属性从标记中的属性中获取初始值,这些属性也存储在单独的属性映射中的 DOM 对象中。在大多数情况下,写入道具只会更改道具,尽管可悲的是,有些道具会将任何更改写入底层 attr(例如),但让我们尽量忽略这一点。99%的时候,你都想用道具。如果您需要使用实际属性,您可能会知道这一点。value
695赞 T.J. Crowder 5/4/2011 #4

我认为 Tim 说得很好,但让我们退后一步:

DOM 元素是一个对象,是内存中的事物。与 OOP 中的大多数对象一样,它具有属性。此外,它还具有在元素上定义的属性的映射(通常来自浏览器读取以创建元素的标记)。元素的某些属性从具有相同或相似名称的属性中获取其初始值(从“value”属性中获取其初始值; 从“href”属性中获取其初始值,但它不完全相同的值; 从“class”属性)。其他属性通过其他方式获取其初始值:例如,属性根据其父元素获取其值;元素始终具有属性,无论它是否具有“style”属性。valuehrefclassNameparentNodestyle

让我们在以下页面中考虑这个锚点: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-xyzdata-data-xyzdatadata-xyzattrdata-xyz

该函数过去有一些复杂的逻辑来获取他们认为您想要的东西,而不是从字面上获取属性。它混淆了这些概念。搬到并旨在将它们分开。简而言之,在 v1.6.0 中,jQuery 在这方面走得太远了,但功能很快就被添加回去,以处理人们在技术上应该使用 .attrpropattrattrattrprop

145赞 Gary Green 5/19/2011 #5

只是 HTML 属性和 DOM 对象之间的区别导致了混淆。对于那些喜欢在DOM元素上执行本机属性(如等)的人来说,这是一个非常热烈的欢迎家庭。对于其他人来说,这只是一层额外的混乱。让我们弄清楚这一点。this.srcthis.valuethis.checked.prop

查看 and 之间差异的最简单方法是以下示例:.attr.prop

<input blah="hello">
  1. $('input').attr('blah'):按预期返回。这里没有假设。'hello'
  2. $('input').prop('blah'):返回 -- 因为它正在尝试这样做 -- 并且该 DOM 对象上不存在这样的属性。它仅作为该元素的属性存在于作用域中,即undefined[HTMLInputElement].blah[HTMLInputElement].getAttribute('blah')

现在我们更改一些内容,如下所示:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): 返回嗯?为什么不是“梨”,因为这是在该元素上最后设置的。因为属性是在输入属性上更改的,而不是 DOM 输入元素本身,所以它们基本上几乎彼此独立工作。'apple'
  2. $('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')

254赞 yunzen 9/28/2011 #6

属性位于 DOM 中;属性位于解析为 DOM 的 HTML 中。

更多细节

如果更改属性,则更改将反映在 DOM 中(有时使用不同的名称)。

示例:更改标签的属性将更改 DOM 中该标签的属性(这是因为它是 JavaScript 中的保留字,不能用于属性名称)。 如果标记上没有属性,则仍具有具有空值或默认值的相应 DOM 属性。classclassNameclass

示例:虽然您的标记没有属性,但 DOM 属性确实存在,但字符串值为空。classclassName

编辑

如果更改一个,则控制器将更改另一个,反之亦然。 此控制器不在 jQuery 中,而是在浏览器的本机代码中。

14赞 naor 2/3/2014 #7

通常,您需要使用属性。 仅将属性用于:

  1. 获取自定义 HTML 属性(因为它未与 DOM 属性同步)。
  2. 获取与 DOM 属性不同步的 HTML 属性,例如获取标准 HTML 属性的“原始值”,例如<input value="abc">.
42赞 Ciro Santilli OurBigBook.com 7/6/2014 #8

肮脏的检查

此概念提供了一个可观察到差异的示例: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 说:disabledbuttondisabled="disabled"

禁用的 IDL 属性必须反映禁用的内容属性。

所以你可能会侥幸逃脱,尽管它很丑陋,因为它不需要修改 HTML。

对于其他属性,如 on ,事情会中断,因为一旦你单击它,它就会变脏,然后添加或删除 content 属性不会再切换 checkednesschecked="checked"input type="checkbox"checked="checked"

这就是为什么你应该主要使用 ,因为它直接影响有效属性,而不是依赖于修改 HTML 的复杂副作用。.prop

61赞 agjmills 7/16/2014 #9

TL;博士

在大多数情况下使用。prop()attr()

属性是输入元素的当前状态。属性是默认值。

属性可以包含不同类型的内容。属性只能包含字符串

评论

1赞 Mou 5/28/2015
如果可能的话,提供一些你所说的简单样本,并显示何时使用。等待答案:)prop() and when to go for attr()
9赞 NkS 12/26/2014 #10

attributes-> HTML

properties-> DOM

评论

10赞 t.niese 12/26/2014
我知道你想说什么,但 HTML 是一种标记语言,而 DOM 是从 HTML 中创建的表示。DOMElement 同时具有特性属性
34赞 Evgenia Karunus 6/12/2015 #11

属性位于您的 HTML 文本文档/文件中(== 想象这是解析 HTML 标记的结果),而
属性位于 HTML DOM 树中(== 基本上是 JS 意义上某个对象的实际属性)。

重要的是,它们中的许多都是同步的(如果你更新属性,html中的属性也会更新;否则)。但是某些属性可能会同步到意外的属性 - 例如,属性对应于 property ,因此classclasscheckeddefaultChecked

  • 手动选中复选框将更改值,但不会更改值.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()

table with preferred usage


为什么你有时想使用 .prop() 而不是 .attr(),而后者是官方建议的?

  1. .prop()可以返回任何类型 - 字符串、整数、布尔值;while 始终返回一个字符串。.attr()
  2. .prop()据说比 快 2.5 倍左右。.attr()
-2赞 zawhtut 10/15/2015 #12

Gary Hole 的答案与解决问题非常相关,如果代码以这种方式编写

obj.prop("style","border:1px red solid;")

由于 prop 函数返回对象,上述代码在某些浏览器中无法正常工作(在我的情况下进行了测试)。CSSStyleDeclarationIE8 with Chrome Frame Plugin

因此将其更改为以下代码

obj.prop("style").cssText = "border:1px red solid;"

解决了问题。

3赞 user2657778 10/18/2015 #13

轻轻提醒使用,示例: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 返回空字符串(右)。

7赞 Peter Girnus 10/25/2015 #14

在 jQuery 1.6 之前,该方法有时会在检索属性时考虑属性值,这会导致相当不一致的行为。attr()

该方法的引入提供了一种显式检索属性值的方法,同时检索属性。prop().attr()

文档:

jQuery.attr()获取匹配元素集中第一个元素的属性值。

jQuery.prop()获取匹配元素集中第一个元素的属性值。

28赞 Kgn-web 12/8/2015 #15

.attr():

  • 获取匹配元素集中第一个元素的属性值。
  • 在页面加载时为您提供在 html 中定义的元素值

.prop():

  • 获取匹配元素集中第一个元素的属性值。
  • 给出通过javascript/jquery修改的元素的更新值
0赞 Parth Trivedi 12/18/2015 #16

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 输出的变化而改变,并带有复选框的完整链接和值checkboxhrefattr()prop()prop()originBoolean(pre-1.6)

  • 我们只能使用其他元素访问 DOM 元素,然后它给出 undefinedprop

<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>

6赞 Bob Stein 6/12/2019 #17

有一件事可以做,但不能做:影响CSS选择器.attr().prop()

这是我在其他答案中没有看到的问题。

CSS 选择器[name=value]

  • 将回应.attr('name', 'value')
  • 但并非总是如此.prop('name', 'value')

.prop()仅影响少数属性选择器

.attr()影响所有属性选择器

评论

1赞 Dave Doga Oz 12/10/2021
最后,有人在谈论使用 和 设置属性及其值。每个人都在谈论这两种方法的用法,但我找不到我要找的东西。谢谢你添加这个。attrpropget
0赞 Rishu Ranjan 5/15/2020 #18

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() 访问它们慢。

评论

0赞 Naftali 2/17/2021
我有 49% 的把握 attr 方法不会在内部调用 prop