jQuery: prop vs attr... 澄清

9

注意,这不是.prop() vs .attr()的重复;那个问题涉及到prop和attr的基本功能,而这个问题则特定于它们作为setter的区别。

在尝试缩小使用.prop()设置什么,以及应该通过.attr()在创建新元素时设置什么的范围时,在使用jQuery 1.7.2进行测试时,我发现prop大约快2.5倍,因此似乎更可取。

我能找到的唯一一份要使用attr设置的事物列表如下:

accesskey,align,background,bgcolor,class,contenteditable,contextmenu,data-XXXX,draggable,height,hidden,id,item,itemprop,spellcheck,style,subject,tabindex,title,valign,width

  1. 这是完整的吗(即,任何不在该列表中的内容 - 如min、max、step等 - 都应使用prop)?

  2. 在测试中,其中一些在使用prop设置时似乎也可以正常工作。测试上述列表时,我使用prop没有设置以下内容时出现问题:

    id,class,align,contenteditable,draggable,hidden,spellcheck,tabindex,title

  3. 对于“仍然可以使用prop设置的要使用attr设置的内容列表”,是否有某种原因仍然应该使用attr进行设置?如果没有,那么在创建基本的<div id="foo" class="bar" draggable="true" title="zipzap">时,250%更快的性能对我来说很不错... :)


重复目标上的一些答案涉及到两种方法作为getter和setter之间的差异,甚至列出了可以使用其中一种访问的属性和特性。 - Kevin B
似乎你的问题更多地是关于属性和属性之间的区别,以及在什么时候应该设置属性而不是属性。然而,这也在重复的答案中得到了很好的解释。链接 - Kevin B
不,这个问题是关于使用两种不同的jQuery方法作为设置器时的区别。所提到的答案只是非常间接地提到了与该问题相关的内容。 - BrianFreud
2个回答

24
我在网上找不到完整的列表。每个人都只是复制了jQuery 1.6博客文章中给出的部分列表。关于#3,Starx在他的评论中解决了这个问题。http://timmywillison.com/提供了更好的细节和适当的讨论。MDN和W3C规范还提到,有各种接口可以将属性设置为属性(https://developer.mozilla.org/en/DOM/element),尽管MDN实际上没有列出它们是哪些。MDN提到,使用属性接口作为设置器比使用getAttribute更脆弱:
"虽然这些接口通常由大多数HTML和XML元素共享,但DOM HTML规范列出了更专业的特定对象的接口。请注意,这些HTML接口仅适用于[HTML 4.01]和[XHTML 1.0]文档,并不能保证与任何未来版本的XHTML一起使用。" HTML 5草案确实旨在向后兼容这些HTML接口,但是它们被认为是“已弃用、支持不佳、很少使用或被认为是不必要的某些功能已被删除”。可以通过完全转向DOM XML属性方法(例如getAttribute())来避免潜在冲突。"
"然而,目前似乎可以安全地假设,在Firefox和Chrome中呈现的任何HTML5 doctype页面已经处于已删除“已弃用、支持不佳”等接口的环境中。"
"因此,我已经针对每种HTML元素类型使用布尔值、字符串和整数值测试了每个属性以及jQuery博客中提到的非属性属性。"
"无论您调用.prop()还是attr(),在1.7.2和1.8pre中,jQuery内部始终会实际使用.prop来:"
async, autofocus, autoplay, checked, controls, defer, disabled, hidden, loop,
multiple, open, readonly, required, scoped, selected

对于HTML元素(不考虑window、document等),除非使用.attr(),否则jQuery不会设置以下任何属性:

accept-charset, accesskey, bgcolor, buffered, codebase, contextmenu, datetime,
default, dirname, dropzone, form, http-equiv, icon, ismap, itemprop, kind, 
language, list, location, manifest, nodeName, nodeType, novalidate, pubdate, 
radiogroup, seamless, selectedIndex, sizes, srclang, style, tagName

最后,jQuery将使用.prop()或.attr()设置以下属性列表。在上面的第一个列表中,无论您使用.attr()还是.prop(),jQuery始终使用.prop()。对于此列表中的属性,jQuery使用您使用的任何方法。如果您使用.prop(),jQuery使用.prop(),反之亦然。无论哪种情况,结果都是相同的。因此,忽略任何潜在的语义考虑,仅考虑.prop()比.attr()快约2.5倍,jQuery 1.6.1博客文章建议使用.attr(),但可以改用.prop(),以显著提高性能:

accept, action, align, alt, autocomplete, border, challenge, charset, cite, 
class, code, color, cols, colspan, contenteditable, coords, data, defaultValue, 
dir, draggable, enctype, for, headers, height, hidden, high, href, hreflang, 
id, keytype, label, lang, low, max, maxlength, media, method, min, name, 
optimum, pattern, ping, placeholder, poster, preload, readonly, rel, required, 
reversed, rows, rowspan, sandbox, scope, shape, size, span, spellcheck, src, 
srcdoc, start, step, summary, tabindex, target, title, type, usemap, value, 
width, wrap

1

尝试用简单的术语来理解。

.attr() 给出元素的属性。该属性是在页面加载时加载的。

.prop() 给出元素的属性,

  • 这可以是元素的状态,例如复选框的情况下,它可以被选中或未选中。
  • 或者,它可以是元素的修改属性,因为默认状态。

这个 问题 包含了你需要知道的所有区别。通常,在处理 DOM 操作部分时,您需要使用属性而不是属性。T.J. 的 答案 真正清楚了这个概念。


那不回答这个问题。你(和那个问题/答案)正在谈论操纵已经在DOM中的元素。我问的是关于创建新元素的问题,这显然还没有在DOM中存在。这也没有解决第三个问题,这可能是最重要的部分。 - BrianFreud
当熟悉本地DOM方法时:$(elem).prop('foo', ...) <=> elem.foo = ...$(elem).attr('foo', ...) <=> elem.setAttribute('foo', ...) - ThiefMaster
@BrianFreud,你误解了答案。一旦你知道了差异及其对DOM映射的影响,你就会自动知道答案。 - Starx
我至少在某种程度上理解差异等问题。但是,你没有抓住重点。这个问题特别询问在创建元素时使用prop设置id等的负面影响是什么?它可以工作,并且速度要快得多 - 但是有什么缺点吗?我可以检查规格、jquery源代码等来找到答案。但是只是让我去做这件事本身并不是一个答案。 - BrianFreud
在面向对象的概念中,从类派生的每个对象都有一组预先存在的属性。 属性是那些更改行为的属性,例如复选框的“checked”属性。 这就是prop()的真正用途所在。 而“id”是赋予元素的标识符,因此被称为属性而不是prop,它具有更多的语义含义。 如果你问我。 - Starx

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