97

Expressions like Element.getAttribute("id") and Element.id return the same thing.

Which one should be used when we need attributes of an HTMLElement object?

Is there any cross browser issue with these methods like getAttribute() and setAttribute()?

Or any impact on performance between directly accessing object properties vs using these attribute methods?

Luc125
  • 5,752
  • 34
  • 35
P K
  • 9,972
  • 12
  • 53
  • 99
  • 1
    Similar question: [Properties and Attributes in HTML](http://stackoverflow.com/questions/6003819/properties-and-attributes-in-html) – sleske Oct 12 '13 at 18:14

7 Answers7

137

getAttribute retrieves the attribute of a DOM element, while el.id retrieves the property of this DOM element. They are not the same.

Most of the time, DOM properties are synchronized with attributes.

However, the synchronization does not guarantee the same value. A classic example is between el.href and el.getAttribute('href') for an anchor element.

For example:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

This behavior happens because according to the W3C, the href property must be a well-formed link. Most browsers respect this standard (guess who doesn't?).

There is another case for the input's checked property. The DOM property returns true or false while the attribute returns the string "checked" or an empty string.

And then, there are some properties that are synchronized one-way only. The best example is the value property of an input element. Changing its value through the DOM property will not change the attribute (edit: check the first comment for more precision).

Because of these reasons, I'd suggest you keep using the DOM properties, and not the attributes, as their behavior differs between the browsers.

In reality, there are only two cases where you need to use the attributes:

  1. A custom HTML attribute, because it is not synced to a DOM property.
  2. To access a built-in HTML attribute, which is not synced from the property, and you are sure you need the attribute (for example, the original value of an input element).

If you want a more detailed explaination, I strongly suggest you read this page. It will take you a few minutes only, but you will be delighted by the information (which I summed up here).

Buzinas
  • 11,597
  • 2
  • 36
  • 58
Florian Margaine
  • 58,730
  • 15
  • 91
  • 116
  • 9
    +1 for generally good advice. The synchronization thing is slighty off though: the `value` property of an input does get its initial value from the attribute but is otherwise not tied to it at all. The `value` attribute is fully synchronized instead with the `defaultValue` property. Likewise `checked` and `defaultChecked`. Except in old IE (<=7 and compatibility modes later), which has broken `getAttribute()` and `setAttribute()`. – Tim Down Apr 23 '12 at 12:29
  • Added your comment as "further explaination" :-) – Florian Margaine Apr 23 '12 at 12:33
  • If you're trying to figure out if a value is non-default, you're better off using attributes. Many modern browsers will return a default value (e.g. `input.formAction`) or empty string (e.g. `a.download`), which makes things ambiguous. The only exception are values that aren't 2-way synced, such as `value`. – Kevin Li Jan 07 '16 at 23:19
  • If id is not set at all in the dom, getAttribute will return null and element.id will return an empty string. Is this a standard? – Maciej Krawczyk Sep 16 '16 at 03:29
  • Another case where you might want to use getAttribute is with
    elements. If you have a
    with a child element that has id="id" or name="id" then formelem.id is the child element, not the id of the form element.
    – Debby Mendez Mar 23 '18 at 21:01
14

getAttribute('attribute') normally returns the attribute value as a string, exactly as defined in the HTML source of the page.

However, element.attribute could return a normalized or calculated value of the attribute. Examples:

  • <a href="/foo"></a>
    • a.href will contain full URL
  • <input type="checkbox" checked>
    • input.checked will be true (boolean)
  • <input type="checkbox" checked="bleh">
    • input.checked will be true (boolean)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width will be 0 (number) before the image is loaded
    • img.width will be 64 (number) when image (or first few bytes of it) is loaded
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img.width will be the calculated 50%
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img.width will be 50 (number)
  • <div style='background: lime;'></div>
    • div.style will be an object
Salman A
  • 262,204
  • 82
  • 430
  • 521
3

.id saves the function call overhead. (which is very small, but you asked. )

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
gdoron
  • 147,333
  • 58
  • 291
  • 367
  • Hi gdoron, just for the sake of curiosity: I tried to find an 'official' explanation of this (beyond the empirical test, which is clear enough ;) ) but with no success. Do you have any link about it? – mamoo Apr 23 '12 at 12:19
3

According to this jsPerf test getAttribute is more slow than id property.

PS

Oddly enough both statements perform very bad on IE8 (compared to other browsers).

mamoo
  • 8,156
  • 2
  • 28
  • 38
3

Always use the properties unless you have a specific reason not to.

  • getAttribute() and setAttribute() are broken in older IE (and compatibility mode in later versions)
  • properties are more convenient (in particular, those corresponding to boolean attributes)

There are some exceptions:

  • accessing attributes of <form> elements
  • accessing custom attributes (although I'd discourage using custom attributes at all)

I've written about this subject a few times on SO:

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Before IE 8, properties and attributes [were treated identically](http://msdn.microsoft.com/en-us/library/dd347148(v=VS.85).aspx). As you alluded to earlier, properties are the way to go. –  Apr 23 '12 at 17:21
  • @MattMcDonald: Yes, that's the brokenness to which I was alluding. I didn't expand on it in this answer because I felt I'd done so enough in other answers I linked to :) – Tim Down Apr 23 '12 at 17:32
0

Try below example to understand this completely. For the below DIV

<div class="myclass"></div>

The Element.getAttribute('class') will return myclass but you have to use Element.className which retrieves it from the DOM property.

Hrushikesh
  • 411
  • 5
  • 10
0

One area where this makes a big difference is with css styling based on attributes.

Consider the following:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

The div with the custom property set directly doesn't reflect the value to the attribute, and is not selected by our attribute selector (div[custom]) in the css.

The div with the custom attribute set using setAttribute, however, is able to be selected using a css attribute selector, and styled accordingly.

Jsilvermist
  • 491
  • 7
  • 16