How to ‘listen’ for attribute changes in JavaScript
It’s nice to have event listeners for events on elements, but how do you listen for something like an attribute change?
Enter MutationObserver
. One of its best qualities is enabling you the ability to watch data not otherwise capable of being “listened” to, like a traditional DOM event.
First, set up the function that will be called by MutationObserver
. It takes just one argument: mutationsList
. Each item in the list is what’s called a MutationRecord
. The callback can do anything you want.
const mutationCallback = (mutationsList) => {
for (const mutation of mutationsList) {
if (
mutation.type !== "attributes" ||
mutation.attributeName !== "data-foo"
) {
return
} console.log('old:', mutation.oldValue)
console.log('new:', mutation.target.getAttribute("data-foo"))
}
}
Next, the MutationObserver
takes your callback when initializing the instance:
const observer = new MutationObserver(mutationCallback)
Of course, we haven’t actually kicked off the observer yet. just call the observe
method on your new variable. Its arguments are the element to observe and an object describing the data you’re observing:
observer.observe(myElement, { attributes: true })
Finally, you can stop observing the changes using the disconnect
method:
observer.disconnect()
And that’s it. Easy, right? Well, just be careful; it can be tempting to create new mutation observers for every little thing. Instead, try to consolidate as much as you can into one observer. You can add subtree: true
when calling the observe
method to listen for changes to child nodes, too!
Check out the full range of options for observable data here.
If you liked what you read, feel free to obliterate that like button. ✅
George is a front-end developer and digital designer living in Oregon. By day, he’s a software engineer on ServiceNow’s design systems team. By night, he is constantly re-arranging his video game collection as a distraction from finally playing one.