DEV Community

Cover image for MutationObserver
Hasan TEZCAN
Hasan TEZCAN

Posted on

MutationObserver

What is the mutation observer?

MutationObserver is a JavaScript API that allows developers to listen for changes to specific elements or nodes in the DOM (Document Object Model). It provides a way to observe and respond to changes that occur within the DOM structure.

The MutationObserver works by registering a callback function to observe a specific target element or node in the DOM. When a change occurs, such as a node being added or removed, the callback function is called with a list of MutationRecord objects that describe the changes that have occurred.

The MutationObserver API provides a powerful tool for building responsive web applications that need to react to changes in the DOM. It can be used to implement a wide range of features, such as lazy-loading content, auto-updating UI elements, and real-time data synchronization.


Let me explain mutation observer through an example.

Our aim is to add an animation when the category's section height changes. We need to listen that operation

before after
before after

In order to do this we need a reference of the category section.

import React, { useRef } from 'react';
import { CategoryItems } from './category-items/category-items';
import { CategoryTitles } from './category-titles/category-titles';
import './categories.scss';

const Categories = () => {
  const categoriesRef = useRef<HTMLDivElement>(null);

  return (
    <div className="categories" ref={categoriesRef}>
      <CategoryTitles />
      <CategoryItems />
    </div>
  );
};

export { Categories };

Enter fullscreen mode Exit fullscreen mode

After preparing the categoriesRef, we can create the mutationObserver structure.

First of all, we need to create mutationObserver

  const mutationObserver = new MutationObserver(async () => {
    console.log('mutationObserver operation');
  });
Enter fullscreen mode Exit fullscreen mode

This is our mutationObserver instance we will call this instance from useEffect

  useEffect(() => {
    if (categoriesRef.current) {
      mutationObserver.observe(categoriesRef.current, {
        childList: true,
        subtree: true,
      });

      return () => {
        mutationObserver.disconnect();
      };
    }
  }, []);
Enter fullscreen mode Exit fullscreen mode
  • We defined mutationObserver.observe with categoriesRef.current which listens to the parameters such as childList and subtree, also you can check this out for more parameters.

  • And also we define the mutationObserver.disconnect() on componentWillUnmount hook for delete listen operation when component closed.

Henceforward when the height change at categoriesRef we will see the console log.

    console.log('mutationObserver operation');
Enter fullscreen mode Exit fullscreen mode

Then we will add the animation handler code piece and define a CSS transition to categoriesRef

  const mutationObserver = new MutationObserver(async () => {
    const categoryTitles = document.getElementById('categoryTitles') as HTMLDivElement | null;
    const categoryItems = document.getElementById('categoryItems') as HTMLDivElement | null;

    if (categoriesRef.current && categoryTitles && categoryItems) {
      if (categoryTitles.clientHeight > categoryItems.clientHeight) {
        categoriesRef.current.style.height = `${categoryTitles.clientHeight}px`;
      } else {
        categoriesRef.current.style.height = `${categoryItems.clientHeight}px`;
      }
    }
  });
Enter fullscreen mode Exit fullscreen mode
.categories {
  transition: height 200ms ease;
}
Enter fullscreen mode Exit fullscreen mode

after

voilà 🎉

Source

Top comments (6)

Collapse
 
sergeyleschev profile image
Sergey Leschev

Great post! In addition to its many uses, it's worth noting that the MutationObserver API can also be useful for automating tasks that require DOM manipulation. With its ability to detect changes in real-time, devs can use this API to trigger certain actions upon specific mutation events, such as updating elements or triggering animations. This makes it a valuable tool for improving both the functionality and user experience of web applications.

Collapse
 
yagmurmutluer9 profile image
Yağmur

awesome, thank you

Collapse
 
hasantezcan profile image
Hasan TEZCAN

🌸

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍

Collapse
 
reacthunter0324 profile image
React Hunter

It's great

Collapse
 
hasantezcan profile image
Hasan TEZCAN

🙏