9

Note, this is not a duplicate of .prop() vs .attr(); that question refers to the basic functionality of prop vs attr, while this question is specific to their differences as setters.

In trying to narrow down what should be set using .prop(), vs what should be set via .attr() when creating a new element, in tests with jQuery 1.7.2, I find that prop is approx 2.5 times faster, so it seems preferable.

The only list of things to be set using attr that I could find gives these for attr:

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

  1. is this complete (ie, anything not in that list - such as min, max, step, etc - should use prop)?

  2. in testing, some of those seem to work fine when set using prop. Testing the above list, I've had no issues setting the following with prop:

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

  3. Is there some reason, for that list of "stuff to set with attr that still work when set with prop", why it should still be set with attr? If not, then 250% faster performance when creating a basic <div id="foo" class="bar" draggable="true" title="zipzap"> seems good to me... :)

Community
  • 1
  • 1
BrianFreud
  • 7,094
  • 6
  • 33
  • 50
  • Several of the answers on the dupe target go into differences between the two methods as getters and setters, even listing out properties and attributes that can be accessed with one or the other. – Kevin B Nov 28 '17 at 16:44
  • It seems though that maybe your question was more along the lines of what's the difference between an attribute and a property, and at what point should you set a property rather than an attribute. That however is also [explained very well in the duplicate](https://stackoverflow.com/a/5884994/400654). – Kevin B Nov 28 '17 at 16:58
  • No, this question was about the difference when using two different jQuery methods as setters. The referenced answer only very tangentally even mentions anything relevant to that question. – BrianFreud Jun 07 '20 at 08:01

2 Answers2

24

I cannot find any complete list online. Everyone who gives any kind of a list just copies the partial one given in the jQuery 1.6 blog post. Regarding #3, Starx sortof addressed this in his comment to an answer here. http://timmywillison.com/ goes into better detail with a decent discussion. MDN and the W3C specs also mentions that there are various interfaces from attributes where they can be set as if they were properties ( https://developer.mozilla.org/en/DOM/element ), though MDN doesn't actually list which ones those are. MDN does mention that using the property interfaces as setters is more brittle than using getAttribute:

"While these interfaces are generally shared by most HTML and XML elements, there are more specialized interfaces for particular objects listed in the DOM HTML Specification. Note, however, that these HTML interfaces are "only for [HTML 4.01] and [XHTML 1.0] documents and are not guaranteed to work with any future version of XHTML." The HTML 5 draft does state it aims for backwards compatibility with these HTML interfaces but says of them that "some features that were formerly deprecated, poorly supported, rarely used or considered unnecessary have been removed." One can avoid the potential conflict by moving entirely to DOM XML attribute methods such as getAttribute()."

However, it seems safe to assume for now that any HTML5 doctype page rendered in Firefox and Chrome is already in an environment where 'deprecated, poorly supported', etc interfaces have already been removed.

Thus I've tested every attribute, as well as the non-attribute properties mentioned in the jQuery blogs, against every every HTML element type, using boolean, string, and int values.

Using 1.7.2 and 1.8pre, whether you call .prop() or attr(), jQuery will internally always actually use .prop for:

async, autofocus, autoplay, checked, controls, defer, disabled, hidden, loop,
multiple, open, readonly, required, scoped, selected

For HTML elements (not considering window, document, etc here), jQuery will not set any of the following attributes unless you use .attr():

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

And finally, jQuery will set the following list of attributes with either .prop() or .attr(). In the first list above, jQuery always uses .prop(), regardless of whether you use .attr() or .prop(). For the attributes in this list, jQuery uses whatever you use. If you use .prop(), jQuery uses .prop(), and vica versa. In either case, the result is the same. So ignoring any potential semantic considerations, just with regards to prop() being ~2.5 times faster than .attr(), the jQuery 1.6.1 blog post suggests that .attr() be used, but .prop() can be used instead, with significant increase in performance:

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
BrianFreud
  • 7,094
  • 6
  • 33
  • 50
1

Try to understand this on simple terms.

.attr() gives the attribute of an element. That attribute when it was loaded on the page.

.prop(), gives the property of the element,

  • this can be the state of an element, like in the case of checkboxes, it can either be checked or unchecked.
  • Or, it can be modified attribute of an element, since the default state.

This question has all the differences you need to know. Generally, when working with DOM manipulation part, you need property rather than attributes. The answer by T.J. really clears the concept.

Community
  • 1
  • 1
Starx
  • 77,474
  • 47
  • 185
  • 261
  • That doesn't address this question. You (and that question/answer) are talking about manipulating elements which are already in the DOM. I'm asking about creating new elements, which obviously are not already in the DOM. Nor does this address #3, which is perhaps the most important part. – BrianFreud Jun 11 '12 at 11:17
  • When familiar with native DOM methods: `$(elem).prop('foo', ...)` <=> `elem.foo = ...` and `$(elem).attr('foo', ...)` <=> `elem.setAttribute('foo', ...)` – ThiefMaster Jun 11 '12 at 11:18
  • @BrianFreud, You misunderstood the answer, once you know the differences and its affect on the DOM map, you will know the answer to your question automatically. – Starx Jun 11 '12 at 11:30
  • I understand, at least to some degree, the differences, etc. However, you're missing the point. This question is specifically asking what negatives there are for setting I'd, etc with prop while creating an element. It works, and it's far faster - but what is the drawback? I can examine the specs, the jquery soure, etc, as welll, to find an answer. But just sending me to go do that is not, itself, an answer here. – BrianFreud Jun 11 '12 at 13:13
  • @BrianFreud, In an OO Concept, every object derived from a class has a set of preexisting attributes. Properties are those, which change the behaviour, like `checked` property of a checkbox. This is where the true use of prop() is done. Where as `id` is identification given to an element, thus called as attribute rather than prop, it has more semantic meaning to it. If you ask me. – Starx Jun 12 '12 at 05:23