⁼================================================================================ gomakethings How to get, set, and remove data attributes with vanilla JavaScript =================================================================================

What is a data attribute ?

A data attribute is a custom attribute on an element that starts with data-*.

It can be used to store information (or state ) about the element, or even just as a selector for JavaScript components.

In this example, the button has a data attribute named [data-click]. It has a value of count.

<button data-click="count">Count Up</button>

Data attributes don’t have to have values, though.

In this example, the button has a data attibute of [data-count], without a value.

<button data-count>Count Up</button>

Now, let’s look at how to manipulate them with vanilla JavaScript.

Custom attributes

While data attributes (starting with data-*) are a common convention, you can create custom attributes, too. Some libraries do this.

For example, Vue does this with v-* attributes:

<div id="app-3">
    <span v-if="seen">Now you see me</span>
</div>

You can use the Element.*Attribute() methods to manipulate custom attributes as well.

let span = document.querySelector('[v-if]');

// Update the value of the [v-if] attribute
span.setAttribute('v-if', 'invisible');

Managing data attributes with the dataset property in vanilla JavaScript

Yesterday, we looked at how to get, set, and remove data attributes in JavaScript.

Today, we’re going to look at how to do the same thing with the Element.dataset property.

An example element

Let’s imagine you have an element with a handful of data attributes on it, like this.

<div id="lunch" data-sandwich="tuna" data-drink="soda" data-side="chips" data-snack="cookie" data-payment-method="credit card">
    Lunch!
</div>

You need to access all of the data attributes on the element.

You could use the techniques we learned about yesterday, but for working with multiple attributes, there’s another way that can be a bit easier.

The Element.dataset property

The Element.dataset property returns a DOMStringMap, an object-like collection of key-value pairs.

If you wanted to get all of the data attributes in the #lunch element from our example, you could do this.

let lunch = document.querySelector('#lunch');
let data = lunch.dataset;

Here, data is a DOMStringMap that looks like this.

let data = {
    drink: 'soda',
    paymentMethod: 'credit card',
    sandwich: 'tuna',
    side: 'chips',
    snack: 'cookie'
};

The Element.dataset property drops the data- prefix and converts the kebab-case used by data attributes to camelCase. The [data-payment-method] attribute is assigned to the key paymentMethod, for example.

You can use the Element.dataset property to assign values as well.

To set a data attribute with the Element.dataset property, skip the data- prefix, and write your properties in camelCase. The property will automatically add the leading data- and convert camelCase to kebab-case.

For example, to change the [data-payment-method] from credit card to cash, you could do this:

lunch.dataset.paymentMethod = 'cash';

Strategies for working with data attributes in vanilla JavaScript

Over the last two days, we’ve learned how to get, set, and remove data attributes using a handful of native methods, as well as with the Element.dataset property.

Today, we’re going to look at some different strategies for working with data attributes.

As JavaScript selectors

One of my favorite ways to use data attributes in projects is as selectors for my JavaScript.

For example, if I had a JavaScript dropdown menu component, I might target it with the [data-dropdown] element.

<li>
    <button data-dropdown>About</button>
    <ul>
        <li><a href="/about">Who We Are</a></li>
        <li><a href="/history">Our Story</a></li>
        <li><a href="/contact">Contact Us</a></li>
    </ul>
</li>
document.addEventListener('click', function (event) {

    // Only run if a [data-dropdown] button was clicked
    if (!event.target.matches('[data-dropdown]')) return;

    // Show or hide the dropdown menu...

});

Abstracting code with target elements

But, you can instead use the data attribute as a general selector for modal toggles that includes information about which element to show when clicked.

<button data-modal="#hey-there">Show Modal</button>

<!-- The rest of the page... -->

<div id="hey-there" hidden>
    <p>👋 Hi!</p>
</div>

Then, you can abstract your JavaScript like this.

// When clicked, show the modal
// (This is NOT accessible. DO NOT implement this!)
document.addEventListener('click', function (event) {

    // Get the ID from the clicked button
    let id = event.target.getAttribute('data-modal');

    // If it's not a [data-modal] button, bail
    if (!id) return;

    // Get and show the target element
    let target = document.querySelector(id);
    target.removeAttribute('hidden');

});

Now, you can drop as many [data-modal] buttons as you want onto the page and they’ll behave similarly, without changing or adding to your JavaScript.