jQuery has an attr()
method which retrieves the value of a given HTML attribute. For instance:
var foo = document.getElementById("foo");
$(foo).attr("id");
But, performance-wise this is not optimal since an jQuery object has to be created just to call the attr()
method. This performs better: foo.id
.
So, ideally we would want to avoid using attr()
. But, can we do that (for any attribute)? I believe foo.id
and foo.value
is "safe" (cross-browser), but I remember having issues with foo.href
.
Here is a list of various attributes that I would like to be able to retrieve "directly":
For any element: foo.id
, foo.name
For anchors: foo.href
, foo.target
, foo.rel
For images, objects, iframes: foo.src
, foo.width
, foo.height
For form elements: foo.checked
, foo.selected
, foo.disabled
, foo.readonly
, foo.type
, foo.value
, foo.action
So the question is: Are the above expressions cross-browser? Can I use them safely?
A link to an article which examines this issue would also be nice.
Edit (based on the answers): The expressions in bold are not safe to use!
1) I don't really think performance is an issue. My guess is that 'foo' is simply a pointer, not an object that takes up space in memory. Not sure about this though.
2) You don't have to create a variable foo at all. $("#foo").attr("id") will do.
3) DOM has several methods for accessing attributes. Try .getAttribute("name"), .setAttribute("name"), and .removeAttribute("name")
Looking at how jQuery handles it:
Check out the jQuery source, and search for this line to see what I mean by "special treatment":
attr: function( elem, name, value, pass ) {
In short: I think it safe to do what you want for most of the attributes listed, except for those shown above.
Only 1 jQuery object is made, and you don't have to worry about manually handling anything.To keep things easy, you could do this:
jQuery's
attr()
method is misleadingly named, badly documented and hides a very important distinction: the difference between attributes and properties, something which appears to be poorly understood by many web developers, particularly those whose introduction to JavaScript has come from jQuery.If you read no further, just take this away: you will almost never need to use attributes. It's almost always better to use the corresponding property. Indeed, this is what jQuery's
attr()
methodusually doesused to do prior to version 1.6.Reasons to use a property and avoid
getAttribute()
andsetAttribute()
when dealing with HTML DOMs:onclick
etc.) are thoroughly broken in IE. Always use a property for an event handler. Another consequence of this is that IE in these modes and versions requires you to usegetAttribute("className")
instead ofgetAttribute("class")
to retrieve theclass
attribute.value
attribute of an<input>
element, are not tied to the property with the same name: once the value of an input has been changed (either by the user or script), getting or setting thevalue
attribute has no effect. Instead, thevalue
attribute is synchronized with thedefaultValue
property.checked
: this is represented in the DOM as a booleanchecked
property while confusion reigns about how to set the checkedness of a checkbox using an attribute. Is itremoveAttribute("checked")
?setAttribute("checked", "")
?setAttribute("checked", false)
? All are wrong, because thechecked
attribute is actually mapped to thedefaultChecked
property.There are some situations where using an attribute may be desirable. For example, the
href
property of an<a>
element always reports a fully qualified URL whilegetAttribute("href")
will return the string specified in the HTMLhref
attribute verbatim. Except, of course, in IE. jQuery'sattr()
does attempt to normalize this kind of inconsistency.Some more information on this subject: http://reference.sitepoint.com/javascript/Element/setAttribute, and also this from MSDN: http://msdn.microsoft.com/en-us/library/dd347148%28v=vs.85%29.aspx
Finally, I strongly recommend using the DOM properties directly wherever possible rather than using jQuery's
attr()
method, but there are special cases (such ashref
) it handles that you need to be aware of. Of the properties you mention, all of them are completely safe to use cross-browser, with the following exceptions:foo.href
andfoo.src
(which suffers from a similar problem) as mentioned above.foo.type
can only be set on an<input>
element before it's been added to the DOM.foo.selected
(where foo is an<option>
element) apparently has a bug in older versions of Safari, as noted in another answer.