Table of contents
1.
Introduction
2.
Definition
3.
Syntax
4.
The Mutation Observer Options
5.
The Mutation Record
6.
Examples
6.1.
HTML Document
6.2.
Example1(Observing Changes To Child Elements)
6.2.1.
JavaScript Code
6.2.2.
Output
6.3.
Example2(Observing For Changes To An Element’s Attribute)
6.3.1.
JavaScript Code
6.3.2.
Output
6.4.
Example3(Observing The Changes For CharacterData)
6.4.1.
JavaScript Code
6.4.2.
Output
7.
Frequently Asked Questions
7.1.
What is a Mutation Observer?
7.2.
When would you use the Mutation Observer?
7.3.
How do you get rid of the Mutation in the Observer?
7.4.
How to know if the DOM has changed?
8.
Conclusion
Last Updated: Mar 27, 2024
Medium

Mutation Observer in JavaScript

Author Aniket Majhi
1 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Welcome readers! We hope that you are doing well.

We will discuss an important concept of JavaScript today. The number of programmers is increasing daily, so if you want to stand out or make an impression, you must be aware of every programming concept.

We will be discussing such an important concept in JavaScript, namely, the Mutation Observer in JavaScript. We will be showing you how it is so important for you to learn by giving different scenarios.

If you want to learn more about Javascript then follow these links, Basics of JavaScript and Learn Starting With JavaScript

This blog will help you understand the whole concept of the JavaScript Mutation Observer and extend your knowledge of JavaScript.

So, without further ado, let’s get started.

Definition

The Mutation Observer in JavScript is a built-in object that allows you to monitor for changes in the DOM tree and fires a callback function to react to the changes.

Let’s now look into the syntax of the mutation observer.

Syntax

The basic steps for creating a Mutation Observer API are as follows,

  • First, create a callback function.
const callback = (mutatations) => {
//the callback function
}
You can also try this code with Online Javascript Compiler
Run Code
  • Then, create an observer with the callback function.
let observer = new MutationObserver(callback);
You can also try this code with Online Javascript Compiler
Run Code
  • After that, We call the Observe() method to start observing the DOM changes.
observer.observe(node, options);
You can also try this code with Online Javascript Compiler
Run Code

The above Observe() method takes two arguments, the node is the root of the subtree to monitor for changes, and the options parameter contains some properties that specify what kind of changes to react on.

  • Finally, If you want to stop observing the DOM changes, you have to call the disconnect() method.
observer.disconnect();
You can also try this code with Online Javascript Compiler
Run Code


You can compile with the help of Online Javascript Compiler for better understanding.

The Mutation Observer Options

As we have already shown, if you want to start observing the DOM changes, you need to call the method Observe(). It accepts two parameters. The second parameter is known as the Mutation Observer Options, which allows us to specify the mutation observer. The different properties are shown below.

  • childList: It is used to observe the mutation in the target node’s child elements.
  • attributes: It is used to observe the mutation of the target node’s attributes.
  • characterData: It is used to observe the mutation of the target node’s data.
  • subtree: It is used to observe the mutation of the target and the target’s descendants.
  • attributeOldValue: It is used to observe the target’s attribute value before the mutation. It is set to true if the attribute value is set to true.
  • characterDataOldValue: It is used to observe the target’s data before the mutation needs to be recorded. It is set to true if the characterData is set to true.
  • attributeFilter: If not all attribute mutations need not be observed, set the attributeFilter to an array of attribute local names.

The Mutation Record

After any changes are made in the DOM tree, the callback function is executed. The changes are passed in the first argument as a list of MutationRecord objects.

The properties of the MutationRecord object are shown below.

  • type: It is the type of mutation. It can be “attributes”“characterData”, or “childList”.
    • “attributes”: If the attribute was modified.
    • “characterData”: If the data was modified.
    • “childList”: If the child element was added or removed.
  • target: It returns the node where the mutation occurred. It returns an element for the “attributes”, a text node for the “characterData”, and an element for the “childList” mutation.
  • addedNodes: It returns the nodes added.
  • removedNodes: It returns the nodes removed.
  • previousSibling: It returns the previous sibling of the added or removed node, or null.
  • nextSibling: It returns the next sibling of the added or removed node, or null.
  • arrributeName: It returns the local name of the changed attribute or null.
  • attributeNamespace: It returns the namespace of the changed attribute or null.
  • oldValue: It returns the previous value only for changes of the attributes or text.

Examples

We will show some examples to show you how to observe the changes in mutation.

Let’s create an HTML document that will be used for all of the examples.

HTML Document

<!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>Document</title>

<style>
    .paragraph{
        background-color: blue;
    }
</style>
</head>
<body>

    <!-- for observing changes in child list -->
    <ul id="parent">
        <li>Child1</li>
        <li>Child2</li>
        <li>Child3</li>
        <li>Child4</li>
        <li class="child">Child5</li>
    </ul>

    <!-- for observing changes in the element's attribute -->
    <p class="paragraph"> This Paragraph will be observed for its attribute changes</p>

    <!-- for observing changes in the data -->
    <p class="data" contenteditable>Edit this text!</p>

    <!-- buttons to start and stop observing for changes  -->
    <button class="start">Start Observing</button>
    <button class="stop" disabled>Stop Observing</button>

    <!-- Button for observing changes  -->
    <button class="observing">Observe Changes</button>

    <script src="mutation_observer.js"></script>
</body>
</html>

Example1(Observing Changes To Child Elements)

Here in this example, we will be observing the child elements of the specific node that are to be added or removed.

JavaScript Code

const par = document.getElementById('parent');
const start_button = document.querySelector('.start');
const stop_button = document.querySelector('.stop');
const observe_button = document.querySelector('.observing');

// setting the Mutationbserver option childList to true
let options = {
    childList: true
}

// creating the MutationObserver object by passing the callback function inside the MutationObserver() object
let observer = new MutationObserver(callback)

// the callback function is defined here
function callback(mutations){
  for(let mutation of mutations){
      if(mutation.type === 'childList') {
          console.log('Mutation Detected on the childList');
      }
  }
}

// The observer button
observe_button.addEventListener('click' , () => {
    let exists = document.querySelector('.child');
    if(exists) {
        par.removeChild(exists);
    }
    else{
        par.insertAdjacentHTML('beforeend' , '\n<li class="child">Child5</li>')
    }
}, false)

// The start button
start_button.addEventListener('click' , () => {
    observer.observe(par , options);
    console.log("Observation Started");
    start_button.disabled = !start_button.disabled;
    stop_button.disabled = !stop_button.disabled;
}, false)


// The stop button
stop_button.addEventListener('click', () => {
    observer.disconnect();
    console.log("Observation Ended");
    start_button.disabled = !start_button.disabled;
    stop_button.disabled = !stop_button.disabled;
}, false)
You can also try this code with Online Javascript Compiler
Run Code


Output

The output is shown below.

Before Observing

After Observing

Example2(Observing For Changes To An Element’s Attribute)

Here in this example, we will be observing the changes in the attributes on a specified element.

JavaScript Code

const par = document.getElementById('parent');
const start_button = document.querySelector('.start');
const stop_button = document.querySelector('.stop');
const observe_button = document.querySelector('.observing');
const attr = document.querySelector('.paragraph');

// setting the Mutationbserver option attributes to true
let options = {
    attributes: true
}

// creating the MutationObserver object by passing the callback function inside the MutationObserver() object
let observer = new MutationObserver(callback)

// the callback function is defined here
function callback(mutations) {
    for (let mutation of mutations) {
        if (mutation.type === 'attributes') {
            console.log(`Mutation Detected on the Attribute: ${mutation.attributeName}`);
        }
    }
}

// the observer button
observe_button.addEventListener('click', () => {
    attr.classList.toggle('paragraph');
}, false)


// the start button
start_button.addEventListener('click', () => {
    observer.observe(attr, options);
    console.log("Observation Started");
    start_button.disabled = !start_button.disabled;
    stop_button.disabled = !stop_button.disabled;
}, false)

// the stop button
stop_button.addEventListener('click', () => {
    observer.disconnect();
    console.log("Observation Ended");
    start_button.disabled = !start_button.disabled;
    stop_button.disabled = !stop_button.disabled;
}, false)
You can also try this code with Online Javascript Compiler
Run Code


Output

The output is shown below.

Before Observing

After Observing

Example3(Observing The Changes For CharacterData)

Here in this example, we will be observing the changes for the characterrData.

JavaScript Code

const par = document.getElementById('parent');
const start_button = document.querySelector('.start');
const stop_button = document.querySelector('.stop');
const observe_button = document.querySelector('.observing');
const attr = document.querySelector('.paragraph');
const chardata = document.querySelector('.data');

// setting the Mutationbserver option characterData to true
let options = {
    characterData: true
}


// creating the MutationObserver object by passing the callback function inside the MutationObserver() object
let observer = new MutationObserver(callback)

// the callback function is defined here
function callback(mutations) {
    for (let mutation of mutations) {
        if (mutation.type === 'characterData') {
            console.log(`Mutation Detected on the CharacterData`);
        }
    }
}

// the start button is defined here
start_button.addEventListener('click', () => {
    if (chardata.childNodes[0]) {
        observer.observe(chardata.childNodes[0], options);
        console.log("Observation Started");
        start_button.disabled = !start_button.disabled;
        stop_button.disabled = !stop_button.disabled;
    }
}, false)

// the stop button
stop_button.addEventListener('click', () => {
    observer.disconnect();
    console.log("Observation Ended");
    start_button.disabled = !start_button.disabled;
    stop_button.disabled = !stop_button.disabled;
}, false)
You can also try this code with Online Javascript Compiler
Run Code


Output

The output is shown below.

Before Observing

After Observing

 

Frequently Asked Questions

What is a Mutation Observer?

The Mutation Observer in JavScript is a built-in object that allows you to monitor for changes in the DOM tree and fires a callback function to react to the changes.

 

When would you use the Mutation Observer?

The Mutation Observer is used when some changes are made in the DOM tree.

 

How do you get rid of the Mutation in the Observer?

To get rid of the Mutation in the Observer, you have to use the disconnect() method that tells the observer to stop watching for mutation.

 

How to know if the DOM has changed?

To know whether the DOM has changed, you can use the Mutation Observer constructor to watch for the mutations in the DOM tree.

Conclusion

In this article, we have extensively discussed the Mutation Observer in JavaScript.

We started with the basic introduction. After that, we discussed a few important points like:

  • Definition
  • Syntax
  • Mutation Observer Options
  • Mutation Record

And finally, we saw some examples of Mutation Overver in JavaScript.
 

We hope that this blog has helped you enhance your knowledge regarding the Mutation Observer in JavaScript. If you would like to learn more, check out our articles on An Introduction to JavascriptUsing Functions in JavaScript20 Projects with JavaScript Code Example and Importance of JavaScript to Web Programming. Do upvote our blog to help other ninjas grow.

Check out this problem - Duplicate Subtree In Binary Tree

Head over to our practice platform Coding Ninjas Studio to practice top problems, attempt mock tests, read interview experiences, follow our guided paths, and crack product based companies Interview Bundle.

Happy Reading!

Live masterclass