为什么jQuery 1.9+的attr()方法没有被弃用?

28

作为一名使用jQuery1.9+的软件开发人员,我是否可以在日常工作中“废弃”attr()方法的使用?


正如许多问题所显示的那样,

关于“使用 attr 还是使用 prop?”存在很多困惑,而在我(开发者)的观点中,对于所有使用 attr() 方法的情况,我们可以使用 prop 来代替:

  1. 向后兼容性: 编写新软件不需要这个;
  2. 性能: John说 "通过 .attr() 方法访问属性会比直接通过 .prop() 访问略慢";
  3. 更改属性值: 可以通过 prop(name,newvalue) 方法更改所有内容。
  4. 删除属性: 可以通过 removeProp(name) 方法删除所有内容。
  5. 检查 HTML 属性值: 浏览器使用 DOM,所有 HTML 都被转换为 DOM,如果 DOM 受到影响,则 attr(name) 方法也受到影响。关于 prop 的“强类型”:它比“html 字符串值”(例如“checked” vs true)更好。
  6. 检查属性是否已定义在“HTML 原始代码”中(假设您的浏览器中的 attr 方法返回 undefined 如果没有)... 那么我们在某些软件中需要这个吗?在表单中,".val() 方法是推荐的 jQuery 方法来获取或设置表单的值"
  7. 跨浏览器一致性: 两者(不仅限于 attr)都是一致的方法。(是吗?)

因此,在目前(2013年)的情况下,我认为在开发新的jQuery代码时没有使用 attr 方法的充分理由... 但是,这也就是说,问题是: 在我的日常任务中使用 attr 方法有充分的理由吗?


  1. 你无论如何都不会这样做
  2. DOM仍然区分属性和属性值
  3. 你永远不需要获取页面源代码
- Bergi
没有一个答案完全回答了你的问题吗?我会说其中一些是可以接受的。 - Joel Peltonen
抱歉,我认为prop-vs-attr的答案是重复的,人们没有看到问题的重点(关于最佳实践,而不是prop-vs-attr的概念)...正如你建议的那样,现在我点击了“接受答案”,但不想投票给我的答案,特别是如果它没有得到投票。 - Peter Krauss
我现在(2014年)看到这个问题获得了很多页面浏览量,但我没有用一个单一的问题短语来表达它,以便与引用的类似问题/答案区分开来...因此,试图表达:“我们能否为attrprop最常见的DOM使用制定一个经验法则?”,或者“什么是最常见的DOM使用方式?”...抱歉,也许是因为我的“表达不清”或者糟糕的英语:只有我在这里发布了这种立场的直接回答。大多数其他答案都是这些的副本 - Peter Krauss
4个回答

30

.attr()没有被弃用,因为它是为了有用的事情而存在的,并且是做这件事情的唯一正确方式(除非使用每个元素的getAttribute函数,它也可以做同样的事情...或者自己解析HTML)。我们讨论这个问题的唯一原因是因为jQuery(和一些旧浏览器(咳咳IE咳咳))错误地混淆了属性和属性值,这种混淆是他们在1.9中修复的。

.attr()检索属性值,而.prop()检索属性。这两个东西是不同的,一直都是(尽管DOM通常有一个属性对应于一个属性值)。如果你有一个<p whatever="value">,其中whatever不是浏览器认识的属性,你会使用.attr()来获取属性值。在大多数浏览器中,.prop()甚至无法看到它。

当你关心最终DOM属性时,请使用.prop()。当你关心实际HTML属性时,请使用.attr()。这不是二选一的问题;你可以在同一代码中同时使用它们,即使一次都不会导致宇宙坍塌(无论如何,只要你正确使用它们)。:)只需使用适合当前工作的那个,并停止试图“弃用”没有问题的东西。

7
案例说明:<span data-foo="bar" data-whatsit="xyz">如果你使用 attr("data-foo"),你会得到 "bar"。如果你使用 prop,你得不到结果,会返回 undefined。你可以使用 data,但这会让jQuery为您的span创建一个数据对象,并预先填充该元素上所有的 data-* 属性,如果您只想获取 data-foo 的值,这是不必要的。 - T.J. Crowder
2
@PeterKrauss: 并非全部。 浏览器不支持的任何内容都不会有相关属性。 任何非标准化的内容同样如此。 等等。 - cHao
5
如果你愿意,也可以避免使用for循环。关键是,你为什么要这样做?这没有任何意义。使用适合工作的正确工具。如果你要获取一个“属性”,就使用attr - T.J. Crowder
4
如果你愿意,你可以发表这样的答案。但我个人认为它是错误的,因为确实存在良好的理由。如果要访问属性,请使用 attr。这不是边缘情况,而是常见情况。 - T.J. Crowder
2
@Nanne 主要示例——非标准/自定义属性——不是一个边角案例,它是大多数编写JavaScript的人经常会(或应该)使用的东西,所以我认为它绝对属于“日常使用”的范畴。 - Anthony Grist
显示剩余9条评论

12
我为您准备了一个演示,链接如下:

http://jsfiddle.net/5REVP/

特别是这一部分:
<div id="example" style="padding:10px"></div>

console.log("style");
var styleAttr = $("#example").attr("style");
console.log(styleAttr); // You get "padding:10px"
var styleProp = $("#example").prop("style");
console.log(styleProp); // You get a CSSStyleDeclaration object

"style" 示例清楚地表明属性与属性值不同(请检查控制台)。
为了可读性、可维护性和向前(以及向后)兼容性,您应该始终针对特定任务使用正确的方法,否则可能会出现方法停止按照您所想行事的情况,.attr() 方法就是一个例子。
.attr() 方法用于获取元素的属性,属性是SGML术语,指的是元素标签内包含的信息,您可以通过检查元素轻松阅读该信息。
  • 如果您获取一个元素的“style”属性,则除了该属性中明确写入的内容外,将不会获得任何其他信息。
  • 如果您获取复选框的“checked”属性,则将获取“checked”或“”。
.prop() 方法用于获取元素的DOM属性。"
  • 如果获取“style”属性,则不会获取设计者在样式属性中编写的内容,而是获取元素的所有实际CSS属性。
  • 如果获取复选框的“checked”属性,则会得到true或false。

@cernunnos,感谢您提供的良好解释和线索...我的观点是jQuery编程是“DOM编程”,所有HTML属性都被映射到DOM对象上...因此,我认为对于99.9%的jQuery应用程序,我不需要使用attr。作为开发人员,我认为style对象字符串更适合99%的应用程序。 - Peter Krauss
实际上,大多数jQuery插件操作的是属性而不是属性(一个通常导致另一个,但它们并不相同)。当目标是操作界面(html)时,最好始终操作属性,因为其他插件/模块期望任何相关的“非默认”行为是“可见”的。我认为你很少需要更改元素的属性,但访问它们是很常见的(例如复选框的checked属性)。 - cernunnos
3
+1(style 是一个很好的例子!)对于 @FrédéricHamidi 的吹毛求疵,自 HTML5 开始,HTML 不再是 SGML 应用程序:*"早期的一些版本的 HTML …… 基于 SGML 并使用 SGML 解析规则。然而,几乎没有任何网络浏览器真正实现了 HTML 文档的 SGML 解析…… 导致的混淆浪费了数十年的生产力。因此,这个版本的 HTML 返回到了非 SGML 基础。"* 尽管我在吹毛求疵,但这并不意味着我们不是在以 SGML 的意义讨论属性。 :-) - T.J. Crowder
@T.J.,非常好的观点。我喜欢他们说“一些早期版本的HTML”而不是“几乎所有早期版本”的说法 :) - Frédéric Hamidi
@FrédéricHamidi:非常正确。基本上并没有HTML1,所以“从HTML2到HTML4”是一个相当大的集合。 :-) - T.J. Crowder
非常棒的回答,我之前并不知道这个区别,这个例子让我非常清楚了解了! - Tony

2
`.attr()` 只能访问 HTML 属性,而 `.prop()` 可以检索不在 HTML 元素上的属性。请参阅文档:
例如,应使用 `.prop()` 方法检索并设置 selectedIndex、tagName、nodeName、nodeType、ownerDocument、defaultChecked 和 defaultSelected 等属性。在 jQuery 1.6 之前,可以使用 `.attr()` 方法检索这些属性,但这不在 `.attr()` 的范围内。它们没有相应的属性,只是属性。

http://api.jquery.com/prop/


0

我的作业...在阅读了@cHao和@cernunnos的好解释之后,以及使用了几个月之后... 我认为我们需要另一个概念来决定,作为程序员,何时使用或不使用prop和attr:

  • HTML源代码及其表示:浏览器将HTML页面加载到浏览器的内存空间中。在内存中保留的是DOM表示,但DOM保留了一些原始内容,如属性cssText属性,这些是“有时持久化的表示”。
    PS:未在“标准DOM”中定义的属性没有映射到DOM属性。当一个(非只读)属性发生变化时,如果存在相应的(映射的)属性,它可以自动更改。

  • DOM状态:动态页面需要直接在DOM中进行更改,这是最终用户看到的。因此,如果页面上有一些“单击和更改”操作,每次DOM转到新的页面表示时,因此每次DOM都有一个新的状态
    当一个DOM-属性发生变化时,所有其他DOM 属性(如果需要)都会一致地发生变化。

有了这些概念,我们可以得出一个"经验法则(用于attr vs prop的使用)":

  1. 使用prop,你有90%的机会它能正常工作...如果你使用jQuery来改变DOM状态(和标准DOM假设),那么成功率将达到99%。
  2. 如果您需要更改或访问data-*属性,请使用.data()方法。
  3. 否则(非DOM、非数据或非标准事物),请检查是否需要使用.attr(),并留出一些时间进行研究(请参见上面的答案)。

2
有点跑题,但为什么如果这个答案是被接受的,它不在其他答案的顶部呢?通常被接受的答案会排在第一位,即使其他答案有更多的投票... 在这里它是最后一个! - DiegoDD
1
@DiegoDD,抱歉几个月之后才回复... 因为没有人读问题,所以这是一个“不同的问题”,不同于引用的相似问题... 那时候这里的答案都是从相似问题中复制粘贴的。 - Peter Krauss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接