Sometimes, we may want to watch for changes in the DOM in our web app.
In this article, we’ll look at how to watch for changes in the DOM with JavaScript.
MutationObserver
One way to watch for DOM changes in our JavaScript web app is to use the MutationObserver
constructor.
For instance, we can write:
const observer = new MutationObserver((mutations, observer) => {
console.log(mutations, observer);
});
observer.observe(document, {
subtree: true,
attributes: true,
});
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
(async () => {
for (let i = 0; i < 5; i++) {
const p = document.createElement("p");
p.textContent = "hello";
document.body.appendChild(p);
await sleep(1000);
}
})();
to create the MutationObserver
instance with a loop to append child elements to the body within the async function.
We insert a new p element after 1 second 5 times.
We pass in a callback into the MutationObserver
constructor that runs when the DOM changes.
Then we call observe
on the element that we want to observe changes for.
subtree
set to true
means that we watch for child element changes.
attributes
set to true
means we watch for element attribute changes.
Other options include:
childList
— set totrue
to observe the target’s childrencharacterData
— set totrue
to observe the target’s dataattributeOldValue
— set totrue
to observe the element’s attribute’s value before the DOM changecharacterDataOldValue
— set totrue
to observe the target’s character data before a change is madeattributeFilter
— set to the attribute’s local names to be observed.
The mutations
parameter has a bunch of properties that have the changes applied.
The mutations.target
property has the target element that’s changed.
mutations.target.lastChild
has the bottommost child node in the element being watched.
mutations.target.lastElementChild
has the bottommost child element node in the element being watched.
Listen to the DOMSubtreeModified Event
Another way to listen for DOM strucuter changes is to listen to the DOMSubtreeModified
event.
For instance, we can write:
document.addEventListener("DOMSubtreeModified", (e) => {
console.log(e);
});
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
(async () => {
for (let i = 0; i < 5; i++) {
const p = document.createElement("p");
p.textContent = "hello";
document.body.appendChild(p);
await sleep(1000);
}
})();
To add an event listener for the document’s DOMSubtreeModified
event.
The e
parameter is an MutationEvent
object.
The e.target
property has the element that’s changed.
e.path
has the path to the element that’s changed as an array of elements leading to the changed element.
e.children
has an HTMLCollection object with the elements changed.
Conclusion
We can use the MutationObserver
and the DOMSubtreeModified
event to listen for changes to the DOM.