How to use MutationObserver to track mutation on the DOM ?
Table of Contents
About
MutationObserver is a web API function that permits to subscribe to change (ie mutation) in the dom and to react to them
You basically:
- Create a callback function that will be called for every mutation
- Create an observer object
- Subscribe to mutation from a designed element with the created observer.
The below section shows a basic example.
Example
- The call back function where mutationList is a list of mutation object and observer is the observer.
function subtreeCallback(mutationList, observer) {
mutationList
.filter(mutation => mutation.target.id=== "containerForAddedNodes" && mutation.type === "childList")
.forEach( (mutation) => {
mutation.addedNodes.forEach(node => {
console.log(`A ${node.localName} child node was added in the ${mutation.target.localName} (${mutation.target.id}) with the text (${node.textContent})`);
});
});
}
- The observer
const observer = new MutationObserver(subtreeCallback);
- Options when subscribing / observing (ie which mutations to observe). We set them to observe only added nodes
const documentObserveOptions = {
childList: true, // Set to true if mutations to target’s attributes are to be observed.
subtree: true, //Set to true if mutations to not just target, but also target’s descendants are to be observed.
};
- Observe the document
observer.observe(document.getElementById("observedId"), documentObserveOptions);
- The javascript that will modify the document on the click of the button
handleClick = (target) => {
target.nextElementSibling.insertAdjacentHTML("beforeend", "<p>Clicked</p>");
}
- Adding a button to add element to the document
<div id="observedId">
<button onClick="handleClick(this)">Click Me</button>
<div id="containerForAddedNodes">
</div>
</div>
Concept
Below you can find the properties of a mutation object.
Options
When subscribing / observing, you can set the subscribing options that target the type of mutation / changes that your want to subscribe.
Property | Description |
---|---|
childList | Set to true if mutations to target’s attributes are to be observed. |
subtree | Set to true if mutations to not just target, but also target’s descendants are to be observed. |
attributes | Set to true if mutations to target’s children are to be observed. |
characterData | Set to true if mutations to target’s data are to be observed. |
attributeOldValue | Set to true if attributes is true or omitted and target’s attribute value before the mutation needs to be recorded. |
characterDataOldValue | Set to true if characterData is set to true or omitted and target’s data before the mutation needs to be recorded. |
attributeFilter | Set to a list of attribute local names (without namespace) if not all attribute mutations need to be observed and attributes is true or omitted. |
Type
The type of the mutation object is just the option name
For instance:
Type | Description |
---|---|
childList | One or more children have been added to and/or removed from the tree |
attributes | An attribute value changed on the element in mutation.target. The attribute name is in mutation.attributeName The previous value is in mutation.oldValue. |
Mutation Record
The object that you get back for each observation called the mutation record is described here