June 11, 2012

jQuery: prop vs attr… clarification

Question by BrianFreud

Possible Duplicate:
.prop() vs .attr()

I’m 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 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

But 1) is this complete (ie, anything not in that list – such as min, max, step, etc – should use prop), and 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

So 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… 🙂

Answer by BrianFreud

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

Answer by Starx

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.

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!