Watch for changes in DOM tree

Harkishen Singh
Zairza
Published in
3 min readNov 14, 2018

The Document Object Model (DOM) is a programming API for HTML and XML documents. It defines the logical structure of documents and the way a document is accessed and manipulated. With the Document Object Model, programmers can create and build documents, navigate their structure, and add, modify, or delete elements and content. Anything found in an HTML or XML document can be accessed, changed, deleted, or added using the Document Object Model.

Basic DOM view in most html pages

In most modern JS frameworks like Angular and React, lazy loading is incorporated ,i.e., the content updates as the user either scrolls down the web page or clicks over any dynamic content.

Now, if we want a script to scan the entire page ( commonly in a Chrome or Firefox extension using content scripts ), the part updated post page loading is always left, since most of the script gets fired as the pages stop loading. So to execute a particular script as the DOM tree refreshes itself, we could do it by Mutation Observer API.

What is Mutation Observer?

Mutation Observer is a Web API provided by modern browsers for detecting changes in the DOM. It provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature which was part of the DOM3 Events specification.

Mutation Events were useful, but at the same time they created some performance issues. The Events are slow and they are fired too frequently in a synchronous way, which caused some undesired browser bugs. The event requests were fired on every single change in the DOM which caused performance issues. For instance, imagine situation scanning for the Facebook home page DOM tree, which each post appended at the end, more than a thousand attributes( including the child nodes and attribute lists ) get appended, resulting in same number of mutation event calls.

Using Mutation Observer

ConstructorMutationObserver()Creates and returns a new MutationObserver which will invoke a specified callback function when DOM changes occur.Methodsdisconnect()Stops the MutationObserver instance from receiving further notifications until and unless observe() is called again.observe()Configures the MutationObserver to begin receiving notifications through its callback function when DOM changes matching the given options occur.takeRecords()Removes all pending notifications from the MutationObserver's notification queue and returns them in a new Array of MutationRecord objects.

The script required to be rendered would be executed in the callback function passed through the constructor of MutationObserver object.

Example

// Select the node that will be observed for mutations
var targetNode = document.querySelectorAll('.class or #id or DOM part');

// Options for the observer (which mutations to observe)
var config = {
attributes: true,
characterData: true,
childList: true,
subtree: true,
attributeOldValue: true,
characterDataOldValue: true
};

// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
for(var mutation of mutationsList) {
if (mutation.type == 'childList') {
console.log('A child node has been added or removed.');
}
else if (mutation.type == 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};

// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
for(let i=0;i< targetNode.length; i++) {
observer.observe(targetNode[i], config);
}
// Later, you can stop observing
observer.disconnect();

Browser compatibility

--

--