6

I have come across 2 ways of getting a value of attribute: first is:

document.getElementById("id").getAttribute("class");
document.getElementById("id").setAttribute("class", "newClass");

the other:

document.getElementById("id").className;

Both can be used to set and get class value or any other value. Are there specific situations where one is preferable? Is one faster than the other? How do they differ? Why even have 2 ways of doing it?

potato
  • 4,479
  • 7
  • 42
  • 99
  • 1
    `document.getElementById("id").setAttribute("class") = "newClass"` is a syntax error; the setter approach is: `document.getElementById("id").setAttribute("class", "newClass")` – David Thomas Oct 31 '15 at 11:33
  • 2
    possible duplicate http://stackoverflow.com/questions/3919291/when-to-use-setattribute-vs-attribute-in-javascript – Ramanlfc Oct 31 '15 at 11:35
  • The attribute may not represent the current state of the element. Both approaches work for class but (can possibly) produce different results for other attributes such as `value`, `checked` and `selected` attribute of input elements, `href` element on links and etc. – Salman A Oct 31 '15 at 12:24

4 Answers4

5

They do different things. The .getAttribute('name') gets the attribute, while .name get the property.

The attribute is the initial value set by the attribute in the HTML code when the element is created. The property is the current value, which may have changed since the element was created.

For some properties the attribute change along with the property, but for some the property and attribute are separate values:

window.onload = function(){
  
  var el = document.getElementById("id");

  console.log("Attribute: " + el.getAttribute("value"));
  console.log("Property: " + el.value);

  console.log('Changing property');
  el.value = 'b';

  console.log("Attribute: " + el.getAttribute("value"));
  console.log("Property: " + el.value);
  
};
<input type="text" id="id" value="a"></div>
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • if you would have changed `el.value = 'b';` to `el.setAttribute("value", "b"); ` it would have printed the same for both – Saar Oct 31 '15 at 13:04
  • @Saar: Yes, but that is only true as long as the property doesn't have a value of its own. Once the property has been set (either by code or by the user entering a value) the value that you get by reading the property is no longer affected by changing the attribute. – Guffa Oct 31 '15 at 13:12
  • This is a little misleading. The *value* attribute was always reflected in the *defaultValue* property, the *value* property reflects the current value (which might be the default, or something else). Setting the *value* property doesn't set the *value* attribute, setting *defaultValue* does (once upon a time it was read only, but not any more). – RobG Oct 31 '15 at 23:27
  • @RobG: What is misleading? I don't see how what you say differs in any way from anything that was said earlier. – Guffa Oct 31 '15 at 23:49
  • @Guffa—for the reasons in my comment. The *value* attribute is reflected in the *defaultValue* property, that's why changing the *value* property doesn't change the *value* attribute. The OP is asking about attributes and properties in general, not one specific case. There are other cases where the attribute and reflected property have different names. – RobG Nov 01 '15 at 22:55
5

Asking 4 questions in one isn't a good idea.

Are there specific situations where one is preferable?

Generally setting the property is preferred as it's simpler and historically more reliable.

Is one faster than the other?

Logically, setting a property should be faster than calling a method, but the difference is likely negligible to irrelevant.

How do they differ?

setAttribute sets the attribute value. Attributes are reflected in properties. Historically, setting the attribute didn't always change the property and vice versa.

Why even have 2 ways of doing it?

Attributes existed in HTML before javascript, you can think of them as what's in the markup. DOM properties were reflections of attributes, mostly. E.g. once upon a time, a form control's value attribute reflected the default value, whereas the value property reflected its actual value. But many of these differences are going away.

Setting a property that is not a reflection of a standard same–named attribute does not create an attribute of that name (except for a couple of exceptions were the property has a different name to it's related attribute such as class/className and for/htmlFor).

There are many articles on attributes vs properties, many are corrupted by jQuery attr vs prop questions but if you read enough you'll get the picture.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • It's not only historically that some attributes and properties are separate, it still works that way for some attributes and properties. – Guffa Oct 31 '15 at 11:51
3

If your code can change different attributes then you would use document.getElementById("id").getAttribute(myVar); //myVar can be "class" document.getElementById("id").setAttribute(myVar, myValue); //myValue can be "newClass"

if you know you are going to change class you can use document.getElementById("id").className;

EDIT: As pointed in the answer above the attribute is set on the HTML, when changing the attribute the property usually changes as well.

Saar
  • 2,276
  • 1
  • 16
  • 14
0

Is one faster than the other?

I just came across a webpage (https://jsperf.com/style-vs-classname/4) testing the speed of 3 different ways to achieve this

// css: .hide { display: none }
document.getElementById("id").style.display = "none";
document.getElementById("id").setAttribute( "class", "hide" );
document.getElementById("id").className( "hide" ); 

Back in 2010 the first alternative was fastest for IE 6-7 and Opera.

In my browser (Chrome 47.0.2526.73 on Ubuntu Chromium 64-bit), the first alternative is 2.7 times faster than the second, and 4 times faster than the third alternative.

Try it out for yourself!

Hasse Björk
  • 1,431
  • 13
  • 19