Has a best-practice around using setAttribute
instead of the dot (.
) attribute notation been developed?
E.g.:
myObj.setAttribute(\"className\", \"nameOfClass\");
myObj.setAttribute(\"id\", \"someID\");
or
myObj.className = \"nameOfClass\";
myObj.id = \"someID\";
You should always use the direct .attribute
form (but see the quirksmode link below) if you want programmatic access in JavaScript. It should handle the different types of attributes (think \"onload\") correctly.
Use getAttribute
/setAttribute
when you wish to deal with the DOM as it is (e.g. literal text only). Different browsers confuse the two. See Quirks modes: attribute (in)compatibility.
From Javascript: The Definitive Guide, it clarifies things. It notes that HTMLElement objects of a HTML doc define JS properties that correspond to all standard HTML attributes.
So you only need to use setAttribute
for non-standard attributes.
Example:
node.className = \'test\'; // works
node.frameborder = \'0\'; // doesn\'t work - non standard attribute
node.setAttribute(\'frameborder\', \'0\'); // works
None of the previous answers are complete and most contain misinformation.
There are three ways of accessing the attributes of a DOM Element in JavaScript. All three work reliably in modern browsers as long as you understand how to utilize them.
1. element.attributes
Elements have a property attributes that returns a live NamedNodeMap of Attr objects. The indexes of this collection may be different among browsers. So, the order is not guaranteed. NamedNodeMap
has methods for adding and removing attributes (getNamedItem
and setNamedItem
, respectively).
Notice that though XML is explicitly case sensitive, the DOM spec calls for string names to be normalized, so names passed to getNamedItem
are effectively case insensitive.
Example Usage:
var div = document.getElementsByTagName(\'div\')[0];
//you can look up specific attributes
var classAttr = div.attributes.getNamedItem(\'CLASS\');
document.write(\'attributes.getNamedItem() Name: \' + classAttr.name + \' Value: \' + classAttr.value + \'<br>\');
//you can enumerate all defined attributes
for(var i = 0; i < div.attributes.length; i++) {
var attr = div.attributes[i];
document.write(\'attributes[] Name: \' + attr.name + \' Value: \' + attr.value + \'<br>\');
}
//create custom attribute
var customAttr = document.createAttribute(\'customTest\');
customAttr.value = \'567\';
div.attributes.setNamedItem(customAttr);
//retreive custom attribute
customAttr = div.attributes.getNamedItem(\'customTest\');
document.write(\'attributes.getNamedItem() Name: \' + customAttr.name + \' Value: \' + customAttr.value + \'<br>\');
<div class=\"class1\" id=\"main\" data-test=\"stuff\" nonStandard=\"1234\"></div>
2. element.getAttribute
& element.setAttribute
These methods exist directly on the Element
without needing to access attributes
and its methods but perform the same functions.
Again, notice that string name are case insensitive.
Example Usage:
var div = document.getElementsByTagName(\'div\')[0];
//get specific attributes
document.write(\'Name: class Value: \' + div.getAttribute(\'class\') + \'<br>\');
document.write(\'Name: ID Value: \' + div.getAttribute(\'ID\') + \'<br>\');
document.write(\'Name: DATA-TEST Value: \' + div.getAttribute(\'DATA-TEST\') + \'<br>\');
document.write(\'Name: nonStandard Value: \' + div.getAttribute(\'nonStandard\') + \'<br>\');
//create custom attribute
div.setAttribute(\'customTest\', \'567\');
//retreive custom attribute
document.write(\'Name: customTest Value: \' + div.getAttribute(\'customTest\') + \'<br>\');
<div class=\"class1\" id=\"main\" data-test=\"stuff\" nonStandard=\"1234\"></div>
3. Properties on the DOM object, such as element.id
Many attributes can be accessed using convenient properties on the DOM object. Which attributes exist depends on the DOM node\'s type, not which attributes are defined in the HTML. The properties are defined somewhere in the prototype chain of DOM object in question. The specific properties defined will depend on the type of Element you are accessing. For example, className
and id
are defined on Element
and exist on all DOM nodes that are elements (ie. not text or comment nodes). But value
is more narrow. It\'s defined on HTMLInputElement
and may not exist on other elements.
Notice that JavaScript properties are case sensitive. Although most properties will use lowercase, some are camelCase. So always check the spec to be sure.
This \"chart\" captures a portion of the prototype chain for these DOM objects. It\'s not even close to complete, but it captures the overall structure.
____________Node___________
| | |
Element Text Comment
| |
HTMLElement SVGElement
| |
HTMLInputElement HTMLSpanElement
Example Usage:
var div = document.getElementsByTagName(\'div\')[0];
//get specific attributes
document.write(\'Name: class Value: \' + div.className + \'<br>\');
document.write(\'Name: id Value: \' + div.id + \'<br>\');
document.write(\'Name: ID Value: \' + div.ID + \'<br>\'); //undefined
document.write(\'Name: data-test Value: \' + div.dataset.test + \'<br>\'); //.dataset is a special case
document.write(\'Name: nonStandard Value: \' + div.nonStandard + \'<br>\'); //undefined
<div class=\"class1\" id=\"main\" data-test=\"stuff\" nonStandard=\"1234\"></div>
Caveat: This is an explanation of how the HTML spec defines and modern browsers handle attributes. I did not attempt to deal with limitations of ancient, broken browsers. If you need to support old browsers, in addition to this information, you will need to know what is broken in the those browsers.
One case I found where setAttribute
is necessary is when changing ARIA attributes, since there are no corresponding properties. For example
x.setAttribute(\'aria-label\', \'Test\');
x.getAttribute(\'aria-label\');
There\'s no x.arialabel
or anything like that, so you have to use setAttribute.
Edit: x[\"aria-label\"] does not work. You really do need setAttribute.
x.getAttribute(\'aria-label\')
null
x[\"aria-label\"] = \"Test\"
\"Test\"
x.getAttribute(\'aria-label\')
null
x.setAttribute(\'aria-label\', \'Test2\')
undefined
x[\"aria-label\"]
\"Test\"
x.getAttribute(\'aria-label\')
\"Test2\"
This looks like one case where it is better to use setAttribute:
Dev.Opera — Efficient JavaScript
var posElem = document.getElementById(\'animation\');
var newStyle = \'background: \' + newBack + \';\' +
\'color: \' + newColor + \';\' +
\'border: \' + newBorder + \';\';
if(typeof(posElem.style.cssText) != \'undefined\') {
posElem.style.cssText = newStyle;
} else {
posElem.setAttribute(\'style\', newStyle);
}
\"When to use setAttribute vs .attribute= in JavaScript?\"
A general rule is to use .attribute
and check if it works on the browser.
..If it works on the browser, you\'re good to go.
..If it doesn\'t, use .setAttribute(attribute, value)
instead of .attribute
for that attribute.
Rinse-repeat for all attributes.
Well, if you\'re lazy you can simply use .setAttribute
. That should work fine on most browsers. (Though browsers that support .attribute
can optimize it better than .setAttribute(attribute, value)
.)
methods for setting attributes(for example class) on an element:
1. el.className = string
2. el.setAttribute(\'class\',string)
3. el.attributes.setNamedItem(object)
4. el.setAttributeNode(node)
I have made a simple benchmark test (here)
and it seems that setAttributeNode is about 3 times faster then using setAttribute.
so if performance is an issue - use \"setAttributeNode\"