Using HTML5 Data Attributes with JavaScript

HTML5 gave us the ability to add arbritrary pieces of information to any element to use behind the scenes for any purpose you wish. These are known as data attributes and I put them to good use in my Interactive Periodic Table. There is plenty of information around on the topic but often with simplistic or contrived examples so here I will present a real-world usage with a simplified version of the Periodic Table.

You can add a custom data attribute to an element by hard-coding it into the HTML, prefixing the name with -data, for example:

Custom data attributes in HTML

<div id="div1" data-manufacturer="nikon" data-model="d6">Nikon D6</div>

Within JavaScript you can access an element's data attributes for reading and writing using its dataset property which is of DOMStringMap type and is basically a collection of key/value pairs. The keys are the names used for the attributes but without the data- prefix, so for the above example we would use manufacturer and model, as shown below.

Reading and writing Custom data attributes in JavaScript

const element = document.getElementById("div1");
console.log(element.dataset.manufacturer); // nikon
console.log(element.dataset.model); // d6
element.dataset.manufacturer = "canon";
element.dataset.model = "EOS 90D";

It is also easy to find elements with certain data attribute values using querySelector, for example:

Finding the element for Nikon D6

const element = document.querySelector("[data-manufacturer='nikon'][data-model='d6']");

Below is a screenshot of the simplified Periodic Table used for this example.

If you click on an element an alert is shown with the name, atomic number and chemical symbol of that element. You have probably guessed how we know which element* to show the details for: using its data attribute.

*I am going to have to use the word "element" quite a lot during this article. This is pretty annoying but I will try to point out whether I am referring to an HTML element or a type of atom unless it is obvious.

The Project

This project consists of an HTML file, a JavaScript file and a few subsiduary files, all of which can be downloaded as a ZIP or cloned from Github using the links below.

Source Code Links

ZIP File

I won't show all the source code, just the bits relevant to data attributes. I have used them several times during this project but to avoid repetition I will just show where we carry out the following tasks:

  • Setting the data-atomicnumber for a (chemical) element on its corresponding (HTML) element
  • Finding an (HTML) element by its (chemical) element's atomic number to set the background colour
  • Retrieving the data-atomicnumber from a clicked (HTML) element to show the (chemical) element's details

To populate the table we iterate a list of elements, adding each to the table with a corresponding data-atomicnumber attribute.

periodictabledisplay.js line 109

currentcell.setAttribute('data-atomicnumber', element.atomicnumber);

Here I have used setAttribute instead of dataset.atomicnumber just to show the alternative.

After the table is populated we need to set the colours to indicate the element's categories. Again we iterate the data, finding the cell corresponding to each element like this:

periodictabledisplay.js line 127

const currentcell = document.querySelector(`[data-atomicnumber='${element.atomicnumber}']`);

As seen in the Nikon D6 example above you can use more than one selector if necessary. In this project we know that the data is static so we will always find a cell but if this is not the case remember to check the return value of querySelector for null. Also, you might need to use querySelectorAll if there can be more than one matching element.

Finally we need to pick up the data-atomicnumber attribute value when an element is clicked.

periodictabledisplay.js line 48

const element = this._periodictable.GetElement(target.dataset.atomicnumber);

What is actually happening here is that we are calling the GetElement method of an instance of a class representing all chemical elements, picking up the dataset.atomicnumber of the target (ie the HTML element that was clicked) to use as the method argument.

So as you can see using data attributes greatly simplifies the process of both finding an HTML element when we need to do something to it (such as setting its colour) and identifying that element when a user interacts with it, for example by clicking on it.

When I started working on the Periodic Table it soon became clear that data attributes were the way to go. There are no doubt other ways to accomplish the same thing but I am not sure what they are as I never gave the matter any thought!