JavaScript MutationObserver function

The MutationObserver interface offers the capability to monitor changes made to the DOM tree. This feature is designed to supersede the older Mutation Events functionality that was part of the DOM3 Events specification.

In intricate web applications, the Document Object Model (DOM) can frequently undergo alterations. As a result, there may be instances when your application must respond to specific changes within the DOM. The MutationObserver interface provides a means to monitor these modifications to the DOM.

JavaScript MutationObserver Syntax

  • Utilizing MutationObserver is quite simple. To begin, you should define a callback function to instantiate an observer, similar to the following example:
  • Example
    
    let obs_var = new MutationObserver(callback);
    
  • The subsequent procedure involves appending it to a DOM node, which can be executed as detailed below:
  • Example
    
    obs_var.observe(node, config);
    

Config is an object with parameters defining the changes to respond to and is returned by the function.

  • childList: alterations to the node's immediate children.
  • subtree: every descendent of a node.
  • attributes: characteristics of the node.
  • attributeFilter: A list of attribute names that allows you to see the ones you want to see.
  • characterData: for node observation.

The callback is executed subsequent to any changes. The observer serves as the second entity, while the alterations are transferred to the first parameter in the form of an array of MutationRecord objects.

How to operate JavaScript MutationObserver

In order to utilize the MutationObserver API, you must begin by:

  • First, you need to define the callback function that will be executed whenever there are alterations in the DOM:
  • Example
    
    function callback(mutations) {
    
        // JavaScript program
    
    }
    
  • Subsequently, create an instance of the MutationObserver and pass the callback function to the object's constructor through the MutationObserver method:

let observer = new MutationObserver(callbackFunction);

  • Next, initiate the observation of changes within the DOM by invoking the observe method.

observer.observe(targetNode, observerOptions);

The observe function comprises two parameters. The target parameter refers to the root of the node subtree that you wish to monitor for any alterations. The observerOptions parameter dictates which DOM modifications should be reported to the observer's callback function.

  • To cease monitoring the DOM updates, invoke the disconnect method.

observer.disconnect;

Examples

The subsequent illustrations demonstrate the utilization of the JavaScript MutationObserver API with an alternative category of data.

Example1

The subsequent example illustrates the fundamental JavaScript MutationObserver API, accompanied by straightforward information.

Example

<!DOCTYPE html>

<html>

  <body>

<h2> JavaScript MutationObserver Function</h2>

    <div contentEditable id="elemobsId"> Click here and <b> ADD </b>...</div>

    <script>

      let observer_var = new MutationObserver(mutationdata => {

        alert("changes happen"); 

      });

      // observe each data of the changes except attributes

      observer_var.observe(elemobsId, {

        childList: true, // observe direct children list

        subtree: true, // observe direct lower descendants

        characterDataOldValue: true, // pass old data to callback

      });

    </script>

  </body>

</html>

Output

The image below illustrates the output generated by a fundamental JavaScript MutationObserver.

Output 1

Insert the characters in the input field

Output 2

After inserting the characters

Example 2

The example below demonstrates the fundamental usage of the JavaScript MutationObserver API with an option set to false.

Example

<!DOCTYPE html>

<html>

<body>

<h2> JavaScript MutationObserver Function</h2>

<div contentEditable id="elemobsId"> Click here and <b> ADD </b>...</div>

<script>

let optiondata = {

childList: false, // observe direct children list

subtree: false, // observe direct lower descendants

characterDataOldValue: false, // pass old data to callback

}

let observer_var = new MutationObserver(mutationdata => {

alert("changes happen");

});

// observe each data of the changes except attributes

observer_var.observe(elemobsId, optiondata);

</script>

</body>

</html>

Output

The image below illustrates the output generated by a fundamental JavaScript MutationObserver.

JavaScript MutationObserver options

You can specify options to define the characteristics of the MutationObserver by providing them as the second argument to the observe function:

Example

let choices= {

    childList: true,

    attributes: true,

    characterData: false,

    subtree: false,

    characterDataOldValue: false

   attributeFilter: ['attr1', 'attr2'],

    attributeOldValue: false,

};

It is not necessary to select every option available. Nevertheless, it is essential that at least one of the following properties is set to true: childList, attributes, or characterData for the MutationObserver to operate correctly; failing to do so will result in the observer method generating an error.

The following properties are included in the MutationRecord object:

  • type: The mutation's type. It is either "characterData," "attributes," or "childList."
  • target: where the change takes place.
  • addedNodes/removedNodes: the newly or recently added nodes.
  • The added or removed nodes' previousSibling or nextSibling, respectively.
  • attributeName/attributeNamespace: the new name or namespace for the attribute.
  • oldValue: The previous value is only for text or attribute changes if attributeOldValue/characterDataOldValue is set as the matching option.

Example

The subsequent illustration demonstrates the fundamental usage of the JavaScript MutationObserver API, incorporating various options.

Example

<!DOCTYPE html>

<html>

<body>

<h2> JavaScript MutationObserver Function</h2>

<div id = "elemobsId"> Click here and <b> ADD </b></div>

 <ul contentEditable id = "programming_language">

        <li> Java </li>

        <li> PHP </li>

        <li> JavaScript </li>

        <li> PYTHON </li>

        <li> PERL </li>

    </ul>

<script>

let list_data = document.querySelector('#programming_language');

let option_data = {

  childList: true,

  attributes: true,

  characterData: false,

  subtree: false,

  attributeFilter: ['one', 'two'],

  attributeOldValue: false,

  characterDataOldValue: false

};

let observer_var = new MutationObserver(mutationdata => {

alert("changes happen");

});

// observe each data of the changes except attributes

observer_var.observe(list_data, option_data);

</script>

</body>

</html>

Output

The image below illustrates the fundamental output of a JavaScript MutationObserver.

Observe the changes in a child element

The mutation method provides the ability to demonstrate functionalities such as starting, stopping, adding, and removing child elements. The subsequent steps illustrate how to implement changes in the child element of the function.

  • In this section, we can generate a list of data in HTML format.
  • Example
    
    <ul id = "programming_language">
    
            <li> Java </li>
    
            <li> PHP </li>
    
            <li> JavaScript </li>
    
            <li> PYTHON </li>
    
            <li> PERL </li>
    
        </ul>
    
  • Develop buttons to implement the desired functionality within the HTML.
  • Example
    
    <button id = "dataStart"> Start Button </button>
    
  • Utilize the query selector in JavaScript to establish a variable that references both the buttons and the data attribute.
  • Example
    
    let list_data = document.querySelector('#programming_language');
    
          let dataStart = document.querySelector('#dataStart');
    

Utilize the mutation function along with a callback that incorporates the variable.

Example

function log_data(mutation data) {

    for (let mutation of mutation data) {

        if (mutation.type === 'childList') {

            console.log(mutation);

        }

    }

}

let observer_var = new MutationObserver(log_data);
  • Include the necessary actions utilizing the mutationobserver variable along with a JavaScript function.
  • Example
    
    dataStart.addEventListener('click', function () {
    
        // create a new item element
    
        let item_value = document.createElement('li');
    
        item_value.textContent = `Bootstrap version ${counter++}`;
    
        // append it to the child nodes of list
    
        list_data.appendChild(item_value);
    
    });
    

    Examples

The subsequent illustrations demonstrate the child list along with its associated data through various operations.

Example 1

The illustration demonstrates the fundamental modifications occurring within the child element of the parent element.

Example

<!DOCTYPE html>

<html>

<body>

<h2> JavaScript MutationObserver Function</h2>

<ul id = "programming_language">

<li> Java </li>

<li> PHP </li>

<li> JavaScript </li>

<li> PYTHON </li>

<li> PERL </li>

</ul>

<div  id = "elemobsId"> Click on the button </div>

<button id = "dataStart"> Start Button </button>

<button id = "dataStop"> Stop Button </button>

<script>

let list_data = document.querySelector('#programming_language');

let dataRemove = document.querySelector('#dataRemove');

let dataStop = document.querySelector('#dataStop');

function log_data(mutation data) {

for (let mutation of mutation data) {

if (mutation.type === 'childList') {

console.log(mutation);

}

}

}

let observer_var = new MutationObserver(log_data);

dataStop.addEventListener('click', function () {

observer_var.disconnect();

// set button states to disconnect MutationObserver Function

dataStart.disabled = false;

dataStop.disabled = true;

});

dataStart.addEventListener('click', function () {

observer_var.observe(list_data, {

childList: true

});

dataStart.disabled = true;

dataStop.disabled = false;

});

</script>

</body>

</html>

Output

The illustration displays the result produced by the JavaScript MutationObserver when monitoring the child element.

Output1

Click start button

Output2

Click stop button

Example 2

The illustration demonstrates the process of adding data within the child element of its parent element.

Example

<!DOCTYPE html>

<html>

<body>

<h2> JavaScript MutationObserver Function</h2>

<ul id = "programming_language">

<li> Java </li>

<li> PHP </li>

<li> JavaScript </li>

<li> PYTHON </li>

<li> PERL </li>

</ul>

<div  id = "elemobsId"> Click on the button </div>

<button id = "dataStart"> Add Button </button>

<script>

let list_data = document.querySelector('#programming_language');

let dataStart = document.querySelector('#dataStart');

function log_data(mutation data) {

for (let mutation of mutation data) {

if (mutation.type === 'childList') {

console.log(mutation);

}

}

}

let observer_var = new MutationObserver(log_data);

let counter = 1;

dataStart.addEventListener('click', function () {

alert('New Child element is added');

// create a new item element

let item_value = document.createElement('li');

item_value.textContent = `Bootstrap version ${counter++}`;

// append values to the child nodes of a given list

list_data.appendChild(item_value);

});

</script>

</body>

</html>

Output

The displayed image illustrates the results produced by the JavaScript MutationObserver in conjunction with the child element.

Output1

Before inserting the last element

Output2

After inserting the last element

Example 3

The example illustrates the data that has been removed from the child element of the parent element.

Example

<!DOCTYPE html>

<html>

<body>

<h2> JavaScript MutationObserver Function</h2>

<ul id = "programming_language">

<li> Java </li>

<li> PHP </li>

<li> JavaScript </li>

<li> PYTHON </li>

<li> PERL </li>

</ul>

<div  id = "elemobsId"> Click on the button </div>

<button id = "dataRemove">Remove Button </button>

<script>

let list_data = document.querySelector('#programming_language');

let dataRemove = document.querySelector('#dataRemove');

function log_data(mutation data) {

for (let mutation of mutation data) {

if (mutation.type === 'childList') {

console.log(mutation);

}

}

}

let observer_var = new MutationObserver(log_data);

dataRemove.addEventListener('click', function () {

// Delete the last item element of the list

alert('Child element is removed);

list_data.lastElementChild ?

list_data.removeChild(list_data.lastElementChild) :

alert('No more child element to remove');

});

</script>

</body>

</html>

Output

The provided image illustrates the result after the final element of the list has been removed.

Output1

Before removing the last element

Output2

After removing the last element

Keep in mind the mutationObserver crucial details.

  • The callback function, which I've given the name mCallback to demonstrate that you may give it any name, will activate every time a valid mutation is discovered and following the conclusion of the watch method.
  • Since childList is the only "kind" of acceptable mutation, it makes sense to search for it when looping through the MutationRecord. In this case, searching for any other type would be useless.
  • A text node can be added or removed from the targeted element using childList, which would also count. This means that it is not necessary to add or remove an element.
  • Conclusion

The JavaScript MutationObserver method allows for monitoring and manipulating lists. Through this functionality, we can interact with the list and its associated child elements using a variety of options.

Input Required

This code uses input(). Please provide values below: