|
<!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> |