Skip to content

Instantly share code, notes, and snippets.

@csalmeida
Last active June 16, 2024 21:59
Show Gist options
  • Save csalmeida/04953f723b444a93dcd1140eff2fcb14 to your computer and use it in GitHub Desktop.
Save csalmeida/04953f723b444a93dcd1140eff2fcb14 to your computer and use it in GitHub Desktop.
Using MutationObserver to listen to attribute changes
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mutation Observer</title>
</head>
<body>
<h1>Mutation Observer</h1>
<ul class="summary" data-date="today">
<li>Lets you react to changes in the DOM.</li>
<li>Examples, know when:
<ul>
<li>an attribute or test has changed on an element</li>
<li>another elements was added or removed from a parent element</li>
</ul>
</li>
<li>Helpful when trying to work with libraries that don't provide their own events.</li>
</ul>
<p id="timestamp-log">Click the button to get a new timestamp</p>
<button id="make-changes">Change list date attribute</button>
<script>
// Mutation Observer requires a a new instance to be set.
// A function if passed as an argument to understand what to do with any detected mutations.
const observer = new MutationObserver(mutations => {
// There could be one or more mutations so one way to access them is with a loop.
mutations.forEach(record => {
// In each iteration an individual mutation can be accessed.
console.log(record);
// In this case if the type of mutation is of attribute run the following block.
// A mutation could have several types.
if(record.type === 'attributes') {
const changedAttrName = record.attributeName;
const newValue = record.target.getAttribute(changedAttrName);
console.log(`Attribute changed! New value for '${changedAttrName}' : ${newValue}`);
}
});
});
// A list to be used as a target below.
const list = document.querySelector('.summary');
// This is the code that tells MutationObserver what to keep an eye on.
// In this case it is the list targeted earlier and
// it will only observe changes to attributes of the elements such as class, id or any other attribute.
observer.observe(list, {
attributes: true
});
/**
* The following code is used to make a change to the list's attributes.
* It updates the list with a new date value and toggles a class.
* This will trigger two mutations on list each time the button is clicked.
* These can be inspected in the console.
* A paragraph is also changed in order to see changes to the current date value in real time.
*/
// Getting the button and paragraph references from the DOM tree.
const button = document.querySelector('#make-changes');
const paragraph = document.querySelector('#timestamp-log');
// Each time the button is clicked grab the current date.
button.addEventListener('click', (event)=> {
// Creating a new date and putting it into a readable format.
const currentDate = new Date();
const time = currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds();
// Update the date attribute on the list with the current date.
list.dataset.date = time;
// Toggle custom-class on the list.
list.classList.toggle('custom-class');
// Update the paragraph to match the new date value.
paragraph.textContent = time;
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment