MutationObserver in a nutshell
MutationObserver helps us watch for changes happening in the DOM. This simple overview will show you how to use MutationObserver.
How do we use MutationObserver?
The first step is to obtain the element we want to watch for changes.
const elementToObserve = document.querySelector("selector");
Once we have the element we want to watch for changes, we need to set up the callback
to execute when any changes occur. The MutationObserver will pass our callback
two parameters:
- A list of changes that occurred. These changes are defined as MutationRecord instances.
- The MutationObserver instance that executed our
callback
. This is useful for stopping the MutationObserver from inside ourcallback
.
The MutationRecord that represents a change contains a few helpful parameters:
type
: The type of change observed, which can be:
-attributes
: When any attribute on the element was changed, for example, if theclass
attribute changed, added, or removed.
-characterData
: We will only see this type if the element we are watching is a CharacterData node.
-childList
: When the tree of child nodes of the element changed, for example, if a child element was added or removed. This will also be the type we will see when the inner content of an element changes, for example, if the text of anh1
element changes.addedNodes
: Contains a list of nodes that were added. This list will be empty if no nodes were added.removedNodes
: Contains a list of nodes that were removed. This list will be empty if no nodes were removed.attributeName
: Contains the name of the attribute that changed. This will benull
if no attributes were changed.attributeNamespace
: Contains the namespace of the attribute that changed. This will benull
if no attributes were changed.previousSibling
: Contains the previous sibling element of the node that was added or removed.nextSibling
: Contains the next sibling element of the node that was added or removed.oldValue
:
- If anattributes
change was observed, this will be the old value of the attribute.
- If acharacterData
change was observed, this will be the old data of the node.
- If achildList
change was observed, this will benull
.target
:
- If anattributes
change was observed, this will be the element that was changed.
- If acharacterData
change was observed, this will be thecharacterData
node.
- If achildList
change was observed, this will be the element whose children were changed.
const callback = (changes, observer) => {
for (const mutation of changes) {
console.log(`🕵 '${mutation.type}' change was observed!`, mutation);
}
};
Now that we have our element to watch and our callback
ready, we can instantiate our MutationObserver instance and start watching for changes. We need to tell the observer what changes to look out for, so when we start the observer, we pass an object along with the element we want to watch. The options we can pass are:
subtree
: If this is set totrue
, all the child elements rooted in the element we are watching will also be observed.childList
: If the observer should watch out for elements being added or removed.attributes
: If the observer should watch out for any attributes being changed.attributeFilter
: Here we can pass a list of attribute names the observer should be watching.attributeOldValue
: If this is set totrue
, the observer will record the previous value of changed attributes.characterData
: If the observer should watch out for changes to character data nodes inside the element it’s watching.characterDataOldValue
: If this is set totrue
, the observer will record the previous value of changed characterData nodes.
const mutationObserver = new MutationObserver(callback);
mutationObserver.observe(elementToObserve, {
attributes: true,
childList: true,
subtree: true
});
To stop the observer, we can call the disconnect
method. We can also do this from inside our callback
function if we need to.
mutationObserver.disconnect();
Browser Support
MutationObserver is supported by all modern browsers.
In conclusion, learning how to use MutationObserver is a great addition to any web developer’s arsenal. Happy coding!