ChatGPT解决这个技术问题 Extra ChatGPT

.prop() 与 .attr()

因此 jQuery 1.6 具有新功能 prop()

$(selector).click(function(){
    //instead of:
    this.getAttribute('style');
    //do i use:
    $(this).prop('style');
    //or:
    $(this).attr('style');
})

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

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

更新

selector = '#id' $(selector).click(function() { //代替:var getAtt = this.getAttribute('style'); //我是否使用:var thisProp = $(this).prop( 'style'); //或: var thisAttr = $(this).attr('style'); console.log(getAtt, thisProp, thisAttr); });

测试

(另见这个小提琴:http://jsfiddle.net/maniator/JpUF2/

控制台将 getAttribute 记录为字符串,将 attr 记录为字符串,但将 prop 记录为 CSSStyleDeclaration,为什么?这对我未来的编码有何影响?

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

N
Naftali

2012 年 11 月 1 日更新

我原来的答案专门适用于 jQuery 1.6。我的建议保持不变,但 jQuery 1.6.1 稍微改变了一些事情:面对预测的一堆损坏的网站,jQuery 团队reverted attr() to something close to (but not exactly the same as) its old behaviour for Boolean attributes。 John Resig 也blogged about it。我可以看到他们遇到的困难,但仍然不同意他更喜欢 attr() 的建议。

原始答案

如果您只使用过 jQuery 而不是直接使用 DOM,这可能是一个令人困惑的变化,尽管它在概念上绝对是一个改进。但是对于使用 jQuery 的无数网站来说并不是那么好,这些网站会因为这种变化而崩溃。

我将总结主要问题:

你通常需要 prop() 而不是 attr()。

在大多数情况下, prop() 执行 attr() 过去所做的事情。在您的代码中用 prop() 替换对 attr() 的调用通常会起作用。

属性通常比属性更容易处理。属性值只能是字符串,而属性可以是任何类型。例如,checked 属性是一个布尔值,style 属性是一个对象,每个样式都有单独的属性,size 属性是一个数字。

如果同时存在同名的属性和属性,通常更新一个会更新另一个,但对于输入的某些属性(例如 value 和 checked)并非如此:对于这些属性,属性始终代表当前状态而属性(旧版本的 IE 除外)对应于输入的默认值/检查性(反映在 defaultValue / defaultChecked 属性中)。

此更改移除了一些 jQuery 魔法卡在属性和属性前面的层,这意味着 jQuery 开发人员将不得不了解一下属性和属性之间的区别。这是一件好事。

如果您是 jQuery 开发人员并且对属性和属性的整个业务感到困惑,那么您需要退后一步并了解一点,因为 jQuery 不再努力保护您免受这些东西的影响。对于该主题的权威但有些干巴巴的词,有规格:DOM4HTML DOMDOM Level 2DOM Level 3。 Mozilla 的 DOM 文档适用于大多数现代浏览器,并且比规范更易于阅读,因此您可能会发现它们的 DOM reference 很有帮助。有一个section on element properties

作为属性比属性更容易处理的一个例子,考虑一个最初选中的复选框。以下是两个可能的有效 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/。


@Neal:DOM 元素是一个对象。属性是该对象的属性,就像任何其他编程对象一样。其中一些道具从标记中的属性获取它们的初始值,这些属性也存储在 DOM 对象中的 separate 属性映射中。在大多数情况下,写入 prop 只会更改 prop,尽管遗憾的是有些 prop 会将任何更改写入底层 attr(例如 value),但让我们尽量忽略这一点。 99% 的时间,您都想使用道具。如果您需要使用实际属性,您可能会知道这一点。
C
Community

我认为 Tim said it quite well,但让我们退后一步:

DOM 元素是一个对象,是内存中的一个东西。像 OOP 中的大多数对象一样,它具有 属性。它还分别具有元素上定义的属性的映射(通常来自浏览器为创建元素而读取的标记)。某些元素的 properties 从具有相同或相似名称的 attributes 中获取它们的 initial 值(value 从“值" 属性;href 从 "href" 属性中获取其初始值,但它不是完全相同的值;className 从 "class" 属性中获取)。其他属性以其他方式获取其初始值:例如,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代码:

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

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

link 对象是真实的,您可以看到访问其上的 属性 和访问 属性 之间存在真正的区别。

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

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

DOM2 HTML(基本上已经过时,请参阅 HTML 规范)

DOM2 核心(已过时)

DOM3 核心(已过时)

DOM4

这些规范具有出色的索引,我建议将它们的链接放在手边;我一直在使用它们。

例如,自定义属性将包括您可能放在元素上以向代码提供元数据的任何 data-xyz 属性(现在这在 HTML5 中有效,只要您坚持使用 data- 前缀)。 (最新版本的 jQuery 允许您通过 data 函数访问 data-xyz 元素,但该函数只是 data-xyz 属性的访问器 [它的作用更多也比这更少] ; 除非您确实需要它的功能,否则我会使用 attr 函数与 data-xyz 属性进行交互。)

attr 函数曾经有一些复杂的逻辑来获取他们认为您想要的东西,而不是从字面上获取属性。它混淆了这些概念。移至 propattr 是为了消除它们的混淆。简而言之,在 v1.6.0 中,jQuery 在这方面走得太远了,但功能 was quickly added backattr 可以处理人们在技术上应该使用 prop 时使用 attr 的常见情况。


C
Community

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

为了完全理解它们是如何工作的,这里有一个关于 HTML 属性和 DOM 属性之间区别的扩展解释:

HTML 属性

句法:

<body onload="foo()">

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

https://i.stack.imgur.com/NGBd6.png

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 属性的作用。请注意,属性与属性完全不同,因为这个事件处理程序分配是无用的并且不会接收事件(body 没有 onload 事件,只有 onload 属性)。

https://i.stack.imgur.com/genBY.png

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

文档

JavaScript:David Flanagan 的权威指南

HTML 属性,Mozilla 开发中心

DOM 元素属性,Mozilla 开发中心

例子

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

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

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

在没有看过这两个函数的新代码的情况下,我可以自信地说,这种混淆更多地与 HTML 属性和 DOM 属性之间的差异有关,而不是与代码本身有关。希望这为您解决了一些问题。

-马特


$.prop() 获取 DOM 属性,$.attr() 获取 HTML 属性。我试图在心理上弥合差距,以便您了解两者之间的区别。
男孩,我现在也很困惑。所以 $('#test').prop('value') 不返回任何东西? .attr('checked') 也不是复选框?但是以前呢?现在您必须将其更改为 prop('checked')?我不明白这种区分的必要性——为什么区分 HTML 属性和 DOM 属性很重要? “很长一段时间” 的常见用例是什么?将两者之间的区别抽象出来有什么错误,因为它们的用例似乎大多重叠?
为什么要区分 HTML 属性和 DOM 属性?当您在浏览器中加载网页时,HTML 会被解析为 DOM,用于视觉呈现。假设您有一个未选中复选框的表单,然后检查它。如果您使用 $.attr() ,则不会检查 HTML 中的正确性。但是 $.prop() 将被检查,这在我们检查时也是正确的。如果您需要使用源代码或其他指出的初始值,请使用 $.attr() 否则使用 $.prop()。此外,在 Chrome 开发人员工具中,元素将 DOM 显示为 html 而不是 HTML SOURCE。
y
yunzen

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

更多细节

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

示例:更改标记的 class 属性将更改 DOM 中该标记的 className 属性(这是因为 class 已被使用)。如果标签上没有属性,则仍然有相应的 DOM 属性,其值为空或默认值。

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

编辑

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


C
Community

只是 HTML 属性和 DOM 对象之间的区别会引起混淆。对于那些对 DOM 元素原生属性(例如 this.src this.value this.checked 等)进行操作的人来说,.prop 是一个非常热烈的欢迎家庭。对于其他人来说,这只是增加了一层混乱。让我们澄清一下。

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

<input blah="hello">

$('input').attr('blah'):按预期返回 'hello'。这里没有惊喜。 $('input').prop('blah'): 返回 undefined - 因为它正在尝试执行 [HTMLInputElement].blah - 并且该 DOM 对象上不存在此类属性。它仅作为该元素的属性存在于范围内,即 [HTMLInputElement].getAttribute('blah')

现在我们像这样改变一些事情:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');

$('input').attr('blah'): 返回 'apple' 嗯?为什么不使用“梨”,因为这是在该元素上最后设置的。因为属性是在 input 属性上改变的,而不是 DOM 输入元素本身——它们基本上几乎是彼此独立工作的。 $('input').prop('blah'): 返回'pear'

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

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

.attr 与 .prop:

第一轮:风格

<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') -- 返回'我改变了值'

* 注意:由于这个原因,jQuery 有一个 .val() 方法,它在内部等效于 .prop('value')


i
isherwood

TL;博士

在大多数情况下,使用 prop() 而不是 attr()

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

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


如果可能的话,请提供一些简单的示例来说明您所说的内容,并说明何时使用 prop() and when to go for attr()。等待答案:)
C
Ciro Santilli Путлер Капут 六四事

脏检查

这个概念提供了一个可以观察到差异的示例: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 ) })

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

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

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

对于 input type="checkbox" 上的 checked="checked" 等其他属性,事情会中断,因为一旦您单击它,它就会变脏,然后添加或删除 checked="checked" 内容属性不再切换检查性

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


P
Pang

全部在 the doc 中:

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

所以使用道具!


E
Evgenia Karunus

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

重要的是,其中许多是同步的(如果您更新 class 属性,则 html 中的 class 属性也会更新;否则)。 某些属性可能会同步到意外属性 - 例如,attribute checked 对应于 property 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())。

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

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


R
Reza Saadati

.attr()

获取匹配元素集中第一个元素的属性值。

为您提供页面加载时在 html 中定义的元素值

.prop()

获取匹配元素集中第一个元素的属性值。

给出通过 javascript/jquery 修改的元素的更新值


n
naor

通常你会想要使用属性。仅将属性用于:

获取自定义 HTML 属性(因为它没有与 DOM 属性同步)。获取不与 DOM 属性同步的 HTML 属性,例如获取标准 HTML 属性的“原始值”,例如


N
NkS

attributes -> HTML

properties -> DOM


我知道你想说什么,但 HTML 是一种标记语言,而 DOM 是由 HTML 创建的表示。 DOMElement 具有属性和属性。
A
Alex Weitz

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

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

文档:

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

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


B
Bob Stein

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

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

CSS 选择器 [name=value]

将响应 .attr('name', 'value')

但并不总是 .prop('name', 'value')

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

输入[名称](感谢@TimDown)

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

输入[值]

输入[名称]

跨度[名称]

input[data-custom-attribute] (.data('custom-attribute') 也不会影响这个选择器)


最后,有人在谈论使用 attrprop 设置属性及其值。每个人都在谈论这两种方法的 get 用法,我找不到我要找的东西。感谢您添加此内容。
K
K.Dᴀᴠɪs

轻轻提醒一下使用prop(),例如:

if ($("#checkbox1").prop('checked')) {
    isDelete = 1;
} else {
    isDelete = 0;
}

上面的函数用来检查checkbox1是否被勾选,如果勾选:return 1;如果不是:返回 0。函数 prop() 在这里用作 GET 函数。

if ($("#checkbox1").prop('checked', true)) {
    isDelete = 1;
} else {
    isDelete = 0;
}

上面的函数用于设置 checkbox1 被选中并始终返回 1。现在函数 prop() 用作 SET 函数。

不要搞砸了。

P/S:当我检查 Image src 属性时。如果 src 为空,prop 返回页面的当前 URL(错误),attr 返回空字符串(正确)。


P
Parth Trivedi

1) 一个属性在 DOM 中;一个属性位于解析为 DOM 的 HTML 中。 2) $( elem ).attr( "checked" ) (1.6.1+) "checked" (String) 将随着复选框状态而改变 3) $( elem ).attr( "checked" ) (pre-1.6) true ( Boolean) 用复选框状态改变

大多数情况下,我们希望将其用于 DOM 对象,而不是像 data-img、data-xyz 这样的自定义属性。

使用 attr() 和 prop() 访问复选框值和 href 时也有一些差异,因为 DOM 输出会随着 prop() 作为来自原点的完整链接和复选框的布尔值(1.6 之前)而改变

我们只能使用 prop 访问 DOM 元素,否则它会给出 undefined

< head> 道具演示


R
Rishu Ranjan

在 prop() 与 attr() 中还有一些注意事项:

应使用 .prop() 方法检索和设置 selectedIndex、tagName、nodeName、nodeType、ownerDocument、defaultChecked 和 defaultSelected..等。这些没有对应的属性,只是属性。

对于输入类型复选框 .attr('checked') //返回选中 .prop('checked') //返回 true .is(':checked') //返回 true

prop 方法返回选中、选中、禁用、readOnly..etc 的布尔值,而 attr 返回定义的字符串。因此,您可以在 if 条件下直接使用 .prop('checked') 。

.attr() 在内部调用 .prop(),因此 .attr() 方法将比直接通过 .prop() 访问它们稍慢。


我有 49% 的把握 attr 方法不会在内部调用 prop
z
zawhtut

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

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

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

因此将其更改为以下代码

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

解决了这个问题。