Playing with HTML elements is common in the DOM, and attributes aren't behind either. Accordingly in this chapter we'll look at all the HTML attribute related stuff in the HTML DOM.

Attribute names and values

Before beginning any discussion on attributes let's first consider the HTML code below. We will base all our explanations on it.

<!DOCTYPE html>
<html lang="en">
    <head>
        <style>
            .blue {color:blue}
            .gold {color: gold}
            #heading {text-transform: uppercase;letter-spacing: 1px}
        </style>
    </head>
   <body>
       <h1 class="blue" id="heading" title="A heading">A heading</h1>
   </body>
</html>                                

So what we simply have here is a style tag to define CSS styles for HTML elements and an h1 element with attributes class, id and title. With the HTML all set up we can now move on to explore DOM attributes.

The attributes property

For a given element node, the attributes property holds all the attributes and their related data for that specific node. For our h1 element it would look something like this.

var ele = document.getElementById("heading");

console.log(ele.attributes);
// NamedNodeMap {0: class, 1: id, 2: title, class: class, id: id, title: title, length: 3}                                

The property returns a NamedNodeMap object that has both numeric and named keys to access different attributes. The length property holds the total number of attributes the selected element has. For each attribute we have an Attr object containing further information regarding it, like its name, its value etc. Let's demonstrate this on a bigger picture for our h1 element.

var ele = document.getElementById("heading");

// the total number of attributes
ele.attributes.length; //  3

// accessing the class attribute
ele.class.name; // "class"
ele.class.value; // "blue"

// accessing the id attribute
ele.id.name; // "id"
ele.id.value; // "heading"                                

The name property gives the name of a given attribute and value gives its value. We can even check for a given attribute by looping through all of them and matching against the one we want, and this is the place where numeric keys can help.

We have seen class and id attributes in action - now go on and explore the Attr object for title yourself in the console.

And in this way we can explore any attribute on any HTML element be it a predefined one, like class, id etc or even a custom one.

The order in which the attributes come inside an HTML element is the order in which they come inside the attribute property. Try swaping the positions of title and class, and then see what you get.

Checking for attributes

Checking for an attribute

To check if an element has a given attribute we can use the hasAttribute() method on the element node. The method simply takes the name of the attribute to check for (case-insensitively) and returns true or false depending on whether it exists or not.

From now onwards we would be skipping the first statement of selecting h1 to prevent repeating the same thing again and again. You would however definitely have to write it in your code!
ele.hasAttribute("class"); // true
ele.hasAttribute("CLasS"); // true
ele.hasAttribute("CLasSs"); // false
ele.hasAttribute("id"); // true
ele.hasAttribute("random"); // false                                

In line 2 above we wrote CLasS, but still the method returned true because the matching is case-insensitive.

Checking for any attributes at all

To check if an element has any attributes at all we can use the hasAttributes() method. Since it doesn't check for any specific attribute it doesn't take any arguments.

ele.hasAttributes(); // true
document.body.hasAttributes(); // false                                

Adding attributes

To add attributes to a given element we can either use the setAttribute() or setAttributeNode() method. Both of them are available on element nodes.

setAttribute()

For setAttribute() it takes two arguments. The first one is the name of the attribute to add, and second one is it's value. Just think of the flow in which you write an attribute in HTML name="value" i.e from left-to-right going from name-to-value.

The method will overwrite existing attribute values if the given attribute already exists:

ele.setAttribute("contenteditable", "true") // makes the element editable
ele.setAttribute("class", "gold"); // class overwritten                                
A heading

setAttributeNode()

The setAttributeNode() method sets a given attribute node on the selected element. So how to create attribute nodes?

The document.createAttribute() method creates an Attr attribute with the provided name whose value has to be set up explicitly using the value property. Remember the Attr object? We discussed it just a few moments ago. Let's see how to do the same thing as above using setAttributeNode():

var att = document.createAttribute("contenteditable"); // an attribute node created
att.value = "true"; // attribute value set
ele.setAttributeNode(att); // attribute added to ele

att = document.createAttribute("class");
att.value = "gold"; // attribute value set

ele.setAttributeNode(att); // attribute added to ele                                

Clearly, as you can see, the setAttribute() method is shorter and simpler than setAttributeNode().

Removing attributes

The removal of attributes can be done simply using removeAttribute() method. Just give it the name of the attribute to be removed and if it is exists, it will remove it completely from the provided element.

ele.removeAttribute("class");                                
A heading

Dealing with classes

Certain attributes in the HTML DOM are given preference over others like class, id, title, contenteditable, in that they have their specific properties directly on their element node. This mean that these attributes can be accessed without going through the attributes object - it is much more convenient to use these direct properties than attributes. The first in this list is the class property and consequently we will be going over it in detail first.

className

The className property, of a given element, holds the value for its class attribute. If the attribute doesn't exist or is empty className will return "".

// Getting class values
ele.className; // blue
document.body.className; // ""

// Setting class values
ele.className = "gold";                                

As you can see className is much simpler than ele.attributes.class.value, so why not use it instead! The value of className can also be used to add classes to elements. Just use the += operator:

ele.className = " gold";
ele.className; // "blue gold"                                
While adding a class we add a space before the new class's name as in above " gold", so that the classes can be differentiated between. gold would've meant class="bluegold" and therefore the class now is a single one - bluegold.

We can also use className to remove class name by using string replace methods but a much better approach in these cases, including adding classes, will be using the classList object.

classList

The classList object is the winner if you want to simply check for, add, replace, toggle, or remove classes. It is a DOMTokenList object with several methods to do the above mentioned and many more taks. Follow along the comments in the following code snippet.

// Number of classes
ele.classList.length; // 1

// Add a class
ele.classList.add("gold");

// Remove a class
ele.classList.remove("blue");

// Replace the first class with the second one
ele.classList.replace("gold", "greyBg");

// Toggle class
// If it is set, remove it
// If it is not set, add it
ele.classList.toggle("gold");
ele.className; // "greyBg gold"
ele.classList.toggle("gold");
ele.className; // "greyBg"                                

You can relate to the names of the method, their purposes. These ae just some methods of classList, the rest of them is your task to explore.

Some other attributes

Besides class many more attributes, as we said earlier are given preference to have their direct properties and they are as follows:

ele.id; // "heading"
ele.title; // "A heading"
ele.contentEditable; // "inherit"
ele.lang; // ""
ele.src; // undefined
ele.href; // undefined                                

In the example above src, href are usually used for images, scripts, frames, anchors etc. All the properties can be used to get or set the values for respective HTML attributes.

In conclusion

And with this we conclude our attributes chapter. It was surely another long one and may have made you think that DOM is pretty tricky. Well you might be feeling this because you've not practiced enough. Go on to the console and play around with HTML attributes. Add styles for various of them and as add or remove them see the effect live on your browser.