题 .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');
})

或者在这种情况下,他们做同样的事情?

如果我  必须切换到使用 prop(),所有的旧 attr() 如果我切换到1.6,呼叫会中断吗?

UPDATE

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,为什么?这对我未来的编码有何影响?


2054
2018-05-03 19:33


起源


这将是一个明确的兴趣: books.google.ca/...
@Neal,这是因为这种变化超越了jQuery。 HTML属性和DOM属性之间的差异是巨大的。
看到j​​Query恢复了变化让我很难过。他们朝着错误的方向前进。
@Neal。是的,它只会使问题进一步复杂化,而不是将两种方法分开。
@BritishDeveloper答案比简单地说明总是使用x或y更复杂,因为它取决于你想要获得的东西。你想要属性,还是想要属性?它们是两个非常不同的东西。 - Kevin B


答案:


2012年11月1日更新

我的原始答案特别适用于jQuery 1.6。我的建议保持不变,但jQuery 1.6.1略有改变:面对预测的一堆破碎的网站,jQuery团队 回复 attr() 与布尔属性的旧行为接近(但不完全相同)的东西。 John Resig也是 关于它的博客。我可以看到他们遇到的困难,但仍然不同意他的偏好建议 attr()

原始答案

如果您只使用过jQuery而不是直接使用DOM,那么这可能是一个令人困惑的变化,尽管它在概念上肯定是一种改进。对于使用jQuery的网站来说,这不太好,但是由于这种变化会破坏。

我将总结一下主要问题:

  • 你通常想要 prop() 而不是 attr()
  • 在大多数情况下, prop() 做什么 attr() 以前做。更换呼叫 attr() 同 prop() 在你的代码中通常会工作。
  • 属性通常比属性更容易处理。属性值可以只是一个字符串,而属性可以是任何类型。例如, checked property是一个布尔值 style property是一个对象,每个样式都有各自的属性 size 财产是一个数字。
  • 如果属性和具有相同名称的属性都存在,通常更新一个将更新另一个,但输入的某些属性不是这种情况,例如 value 和 checked:对于这些属性,属性始终表示当前状态,而属性(旧版IE中除外)对应于输入的默认值/ checkedness(反映在 defaultValue / defaultChecked 属性)。
  • 这个更改删除了一些在属性和属性前面停留的魔法jQuery层,这意味着jQuery开发人员必须学习一些关于属性和属性之间的区别。这是件好事。

如果你是一个jQuery开发人员并且对整个业务的属性和属性感到困惑,那么你需要退后一步并学习一点,因为jQuery不再那么努力地保护你不受这些东西的影响。对于关于这个主题的权威但有点干的词,有规格: DOM4HTML DOMDOM级别2DOM级别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") ) {...}

这实际上是世界上最简单的事情 checked 布尔属性,自1995年以来在每个主要的脚本浏览器中都存在并且完美无缺:

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/

1735
2018-05-03 23:06



@Neal:如果你想知道DOM元素具有哪些属性以及属性如何为其值设定种子,请保持这些链接: DOM2 HTML规范, DOM2 规范,和 DOM3 规范。每种情况下的指数都很优秀,可以直接与您联系,详细描述该物业的价值,等等。 - T.J. Crowder
@Neal:Re使它与众不同:信息的来源和性质。看看蒂姆的 value 例如,例如。一个叫做的函数 attr 检索 属性  value 而不是属性“价值”没有多大意义(并且它们可以是不同的)。向前走, attr 做属性和 prop 做房产会更清楚,虽然过渡对某些人来说会很痛苦。不要采取错误的方式,没有什么比回过头来阅读规范以了解属性是什么。 - T.J. Crowder
@Neal:DOM元素是一个对象。属性是该对象的属性,就像任何其他编程对象一样。其中一些道具从标记中的属性获取其初始值,这些属性也存储在一个DOM对象中 分离 属性图。在大多数情况下,写一个道具只会改变道具,虽然遗憾的是有一些道具可以将任何变化写入底层的attr(value 例如),但让我们试着大多忽略它。 99%的时间,你想要使用道具。如果您需要使用实际属性,您可能会知道这一点。 - T.J. Crowder
@Tim: “改变了 value 输入的属性不会改变它 value 现代浏览器中的属性“ 我不认为这样做,这就是为什么我开始使用它作为一个例子,但是当我开始编写示例代码时,如果它没有在Chrome,Firefox,Opera,IE上进行更新,那就太大了... - jsbin.com/ahire4 原来那是因为我正在使用 input[type="button"] 为了我的实验。它 不 更新a上的属性 input[type="text"]  - jsbin.com/ahire4/2 谈论复杂的!!不只是元素,而是 类型 它... - T.J. Crowder
$('#chk').checked  决不 工作......这根本不是合适的jQuery ...... - Neal


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

DOM元素是一个对象,一个在内存中的东西。像OOP中的大多数对象一样 性能。它还单独包含元素上定义的属性的映射(通常来自浏览器读取以创建元素的标记)。一些元素 性能 得到他们的 初始 价值来自 属性 具有相同或相似的名称(value 从“value”属性获取其初始值; href 从“href”属性获取其初始值,但它不是完全相同的值; className 来自“类”属性)。其他属性以其他方式获取其初始值:例如, parentNode property根据其父元素获取其值;一个元素总是有一个 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”|
|名称:“fooAnchor”|
| id:“fooAnchor”|
| className:“test one”|
|属性:|
| href:“foo.html”|
|名称:“fooAnchor”|
| id:“fooAnchor”|
| class:“测试一个”|
+ ------------------------------------------- +

请注意,属性和属性是不同的。

现在,尽管它们是截然不同的,因为所有这些都是从头开始设计的,而不是从头开始设计,如果你设置它们,许多属性会回写它们派生的属性。但并非所有人都这样做,正如你所看到的那样 href上面,映射并不总是直接“传递价值”,有时会涉及到解释。

当我谈到属性是对象的属性时,我不是在抽象地说。这是一些非jQuery代码:

var link = document.getElementById('fooAnchor');
alert(link.href);                 // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"

(这些值与大多数浏览器一样;有一些变化。)

link 对象是一个真实的东西,你可以看到访问一个真正的区别 属性 在它上面,访问一个 属性

正如蒂姆所说, 绝大多数 当时,我们希望与物业合作。部分原因是因为它们的值(甚至是它们的名称)在浏览器中往往更加一致。我们大多只希望在没有与之相关的属性(自定义属性)时使用属性,或者当我们知道对于该特定属性时,属性和属性不是1:1(与 href 和上面的“href”)。

标准属性在各种DOM规范中列出:

这些规格有很好的索引,我建议保持链接方便;我一直都在使用它们。

自定义属性包括,例如,任何 data-xyz 您可能在元素上添加元数据以向代码提供元数据的属性(现在,只要您坚持使用HTML5,这就是HTML5的有效属性) data- 字首)。 (jQuery的最新版本允许您访问 data-xyz 元素通过 data 功能,但功能是  只是一个访问者 data-xyz 属性[它做得越来越少];除非你真的需要它的功能,否则我会使用它 attr 与...互动的功能 data-xyz 属性。)

attr 函数曾经有一些复杂的逻辑来获得他们想要的东西,而不是字面上得到属性。它混淆了这些概念。搬到 prop 和 attr 是为了解除他们的混乱。简而言之,在v1.6.0中jQuery在这方面走得太远了,但是功能性 很快被加回来了 至 attr 处理人们使用的常见情况 attr 从技术上讲他们应该使用 prop


623
2018-05-04 14:27



哇。新的1.6.1更新确实使这个问题无效......(但不多)但该链接现在基本上回答了它 - Neal
它没有为我取消它,我只是使用jquery1.7修复了一个错误,我在那里设置.attr('class','bla')并且它无法正常工作.prop('className','bla'工作 - PandaWood
@PandaWood: .attr('class', 'bla') 按照我的预期工作 1.7.0, 1.7.1,和 1.7.2 在Chrome 17,Firefox 11,Opera 11,IE6,IE8,IE9和Safari 5上。 - T.J. Crowder
谢谢,在我的情况下必须有一些特定的东西,让我检查一下,然后回来一个测试用例。但是改变我们现在拥有的代码,简单地“prop / className”,而不是“attr”修复了当我们从jquery1.4移动到1.7时在我们所有浏览器上发生的巨大错误 - PandaWood
@ T.J.Crowder回复: .data  - 它会的 读 属性的默认值(如果存在),但如果您写入它,它将更改隐藏 属性 元素,而不是更新属性。 - Alnitak


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

为了完全理解它们是如何工作的,这里是对HTML属性和DOM属性之间差异的扩展解释:

HTML属性

句法:

<body onload="foo()">

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

可视化: HTML Attributesclass属性显示在正文中。它可以通过以下代码访问:

var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");

属性以字符串形式返回,并且从浏览器到浏览器可能不一致。但是,它们在某些情况下至关重要。如上所示,IE 8 Quirks Mode(及以下)需要get / set / removeAttribute中DOM属性的名称而不是属性名称。这是了解差异的重要原因之一。

DOM属性

句法:

document.body.onload = foo;

目的: 提供对属于元素节点的属性的访问。这些属性与属性类似,但只能通过JavaScript访问。这是一个重要的区别,有助于阐明DOM属性的作用。 请注意,属性与属性完全不同,因为此事件处理程序分配是无用的并且不会接收事件(正文没有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属性之间的差异有关,而不是与代码本身有关。希望这能为你解决一些问题。

-Matt


235
2018-05-03 20:05



@Matt对此一无所知 prop() 在jQuery .... - Neal
$.prop() 获取DOM属性, $.attr() 获取HTML属性。我试图在心理上弥合差距所以你可以理解两者之间的差异。
男孩,我现在也很困惑。所以 $('#test').prop('value') 不归还什么?也没有 .attr('checked') 一个复选框?但它习惯了吗?现在你必须把它改成 prop('checked')?我不明白这种区别的必要性 - 为什么区分HTML属性和DOM属性很重要?进行此更改的常见用例是什么? “很长一段时间”?什么是 错误 通过抽象两者之间的区别,因为看起来他们的用例大多重叠? - BlueRaja - Danny Pflughoeft
@BlueRaja:因为这两个概念之间存在严重的潜在差异,如果你像jQuery一样在地毯下刷它,会导致意外的失败。 value 是最明显的案例之一,因为 value 属性会给你一个字段的当前值,但是 value 属性将为您提供在中声明的原始值 value="..." 属性,实际上是 defaultValue 属性。 (虽然这个特殊情况再次被IE <9中的错误搞糊涂了。) - bobince
@BlueRaja:答案更复杂。 :-) 设置 attr('value', ...) 在jQuery <1.6中设置属性,因此当前值更改而默认值不更改。在1.6中它设置了属性,因此理论上默认值会改变,而当前值则不会。但是,有(更多)浏览器与确切设置的不一致 value 属性呢。在IE中它也设置当前值;在某些浏览器中,如果之前尚未设置当前值,则仅设置当前值。 [呼喊] - bobince


属性在DOM中; HTML中的属性被解析为DOM。

更多细节

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

示例:更改 class 标签的属性将改变 className DOM中该标记的属性。 如果标记上没有属性,则仍具有相应的DOM属性,其属性为空或默认值。

示例:虽然您的标签没有 class 属性,DOM属性 className 确实存在空字符串值。

编辑

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


233
2017-09-27 16:55



那么这是否意味着更新属性更好,因为那样你就确保属性和属性都得到更新并且是一致的? - Luke
@Luke DOM是内部技术代表,模型。 HTML属性是外部表示,视图。如果更改一个,另一个将由控制器更改,反之亦然。 - HerrSerker
@Luke看看这个: jsfiddle.net/Pms3W - HerrSerker
@HerrSerker所以他们都通过控制器保持同步?我假设这只是在jQuery的attr和prop方法中?这是对你的小提琴的修改,我在这里进一步探索 - jsfiddle.net/v8wRy  - 到目前为止,他们似乎是等同的。 - Luke
“如果更改一个,另一个将由控制器更改,反之亦然。此控制器不在jQuery中,而是在浏览器的本机代码中。”这是 不 对于大多数属性/属性都是true。对于大多数人来说,它只是一个单向转换,其中属性决定了 初始 相应属性的值。前两个答案详细解释了这一点。 - ᴠɪɴᴄᴇɴᴛ


只是HTML属性和DOM对象之间的区别导致混淆。对于那些习惯于对DOM元素本地属性采取行动的人来说 this.src  this.value  this.checked 等等, .prop 对家人来说是一个非常热烈的欢迎。对于其他人来说,这只是一层混乱。让我们清楚一点。

看看之间区别的最简单方法 .attr 和 .prop 是以下示例:

<input blah="hello">
  1. $('input').attr('blah'):返回 'hello'正如所料。这里没有惊喜。
  2. $('input').prop('blah'):返回 undefined  - 因为它正在努力做到 [HTMLInputElement].blah  - 并且该DOM对象上不存在此类属性。它只作为该元素的属性存在于范围内,即 [HTMLInputElement].getAttribute('blah')

现在我们改变一些事情:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'):返回 'apple' 是吗?为什么不在这个元素上设置“梨”。因为属性是在输入属性上更改的,而不是DOM输入元素本身 - 它们基本上几乎彼此独立工作。
  2. $('input').prop('blah'):返回 'pear'

你真正需要小心的事情就是 在整个应用程序中,不要将这些用法混合使用相同的属性 由于上述原因。

看一下展示差异的小提琴:  http://jsfiddle.net/garreh/uLQXc/


.attr VS .prop

第1轮:风格

<input style="font:arial;"/>
  • .attr('style')  - 返回匹配元素的内联样式,即 "font:arial;"
  • .prop('style')  - 返回样式声明对象,即 CSSStyleDeclaration

第二轮:价值

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


132
2018-05-19 10:18



@Neal因为它更好地引用了jquery函数的结构。 “$('input')。prop('blah'):返回undefined - 因为它正在尝试[HTMLInputElement] .blah - 并且该DOM对象上没有这样的属性。它只作为属性存在于作用域中该元素,即[HTMLInputElement] .getAttribute('blah')“ - Uğur Gümüşhan
似乎与文档不同, api.jquery.com/prop:“.prop()方法应该用于设置disabled和checked而不是.attr()方法。应该使用.val()方法来获取和设置值。” - swan
我不明白为什么在更改类或样式属性时属性也会更改 jsfiddle.net/featon/Jbw6m/3 ? - Damian


TL; DR

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

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

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


48
2017-07-16 09:45



如果可能的话,几乎没有简单的样本,并且还显示何时使用 prop() and when to go for attr()。等待回答:) - Mou


肮脏的检查

这个概念是一个可以观察到差异的例子: 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>

对于某些属性,如 disabled 上 button,添加或删除内容属性 disabled="disabled" 总是切换属性(在HTML5中称为IDL属性),因为 http://www.w3.org/TR/html5/forms.html#attr-fe-disabled 说:

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

所以你可能会侥幸逃脱它,虽然它很难看,因为它不需要修改HTML。

对于其他属性,如 checked="checked" 上 input type="checkbox"事情破裂,因为一旦你点击它,它就会变脏,然后添加或删除 checked="checked" 内容属性 不再切换检查

这就是你应该主要使用的原因 .prop,因为它直接影响有效性质,而不是依赖复杂的副作用。


34
2017-07-06 11:43



为了完整性,还可以尝试以下变化:1)在单击按钮之前检查然后取消选中第一个复选框2)(对于这个,您需要更改代码段)给第一个输入a checked 属性: checked="checked" - ᴠɪɴᴄᴇɴᴛ


一切都在文档中:

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

所以使用道具!


32
2018-05-03 19:35



所以这意味着当我切换到1.6时,很多事情会破裂? - Neal
不,这只是一种不一致的行为,如果之前有效,它将始终与jQuery 1.6一起使用,它只是支柱更安全;) - Arnaud F.
我似乎记得。$.attr() 在我使用它的大部分时间检索属性,而不是“有时”。由它引起的混乱今天仍然是共鸣。可悲的是,我在寻找一个问题时遇到了很多麻烦 明确 阅读HTML属性与DOM属性,所以我可能会在这里写一个答案。
@ Arnaud-f不对。使用attr('checked')检查复选框的1.6之前的所有代码现在都将被破坏。 - CaptSaltyJack
@Matt McDonald:什么样的“......找不到麻烦 明确 阅读HTML属性与DOM属性...“你的意思是?属性(反映和否则)描述在 DOM2 HTML规范;你可能还需要参考 DOM2 和 DOM3 眼镜。 - T.J. Crowder


属性 在你的HTML中 文本文件/文件 (==想象这是你的html标记解析的结果),而
性能是HTML格式 DOM树 (==基本上是JS意义上某个对象的实际属性)。

重要的是,其中许多是同步的(如果你更新 class 属性, class html中的属性也会更新;否则)。  某些属性可能会同步到意外的属性 - 例如, 属性  checked 对应于 属性  defaultChecked, 以便

  • 手动检查复选框将更改 .prop('checked') 价值,但不会改变 .attr('checked') 和 .prop('defaultChecked') 值
  • 设置 $('#input').prop('defaultChecked', true) 也会改变 .attr('checked'),但这在元素上不可见。

经验法则是.prop() 方法应该用于布尔属性/属性以及html中不存在的属性   (例如window.location)。所有其他属性(你可以看到的属性)   html)可以而且应该继续被操纵 .attr()   方法。 (http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/

这是一张显示位置的表格 .prop() 是优选的(即使 .attr() 仍然可以使用)。

  table with preferred usage


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

  1. .prop() 可以返回任何类型 - 字符串,整数,布尔值;而 .attr() 总是返回一个字符串。
  2. .prop() 据说比它快约2.5倍 .attr()

26
2018-06-12 05:56



有些东西已经改变了,比如: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class'), 要么 $('#myTextBox').prop('type', 'button')。等等...
@Wolf先生,对不起? - lakesare
@Wolf先生,对不起,我不明白你的意思。什么“改变了”?语法总是那样的。 - lakesare
我认为答案中的表格是不必要的。因为 .prop() 适用于所有属性。你不想标记所有属性 .prop() 专栏,你呢?
@Wolf先生,我认为这是必要的,因为,如前所述,它“显示在哪里 .prop() 是优选的(即使 .attr() 仍然可以使用)' - lakesare


.attr()

  • 获得一个的价值 属性 对于匹配元素集中的第一个元素。
  • 为您提供元素的值,因为它是在页面加载的html中定义的

.prop()

  • 获得a的价值 属性 对于匹配元素集中的第一个元素。
  • 提供通过javascript / jquery修改的元素的更新值

18
2017-12-08 09:14