Skip to content

Instantly share code, notes, and snippets.

@isocroft
Last active October 25, 2025 16:32
Show Gist options
  • Select an option

  • Save isocroft/9dc52eaa6c2fe5327eb153b9479c9dee to your computer and use it in GitHub Desktop.

Select an option

Save isocroft/9dc52eaa6c2fe5327eb153b9479c9dee to your computer and use it in GitHub Desktop.
a ReactJS hook for observing DOM mutations as they occur upon DOM manipuation
import { useState, useEffect } from "react";
function useObserveDOMMutations (callback = (() => undefined), options = { childList: true, subtree: true, attributes: false, attributeFilter: [], attributeOldValue: false, characterData: false, characterOldValue: false }, rootElementId = '#root') {
const [observer] = useState(() => (typeof window !== "undefined" ? new MutationObserver(function (mutations, instance) {
const reactAppRootElem = window.document.querySelector(rootElementId);
if (!reactAppRootElem) {
instance.disconnect();
return;
}
callback(mutations);
}) : {}));
useEffect(() => {
function onPageIsInteractive() {
if (window.document.readyState === "interactive"
|| window.document.readyState === "complete") {
observer.observe(
window.document,
options.attributes === false
/* @HINT: Ensure that the mutation observer doesn't throw an error/exception */
/* @CHECK: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#exceptions */
? Object.assign({ attributeFilter: undefined }, options)
: options
);
}
}
window.document.addEventListener("readystatechange", onPageIsInteractive, false);
return () => {
let mutations = typeof observer.takeRecords === "function"
? observer.takeRecords()
: [];
observer.disconnect();
if (mutations.length > 0) {
callback(mutations);
}
window.document.removeEventListener("readystatechange", onPageIsInteractive, false);
};
}, []);
}
@isocroft
Copy link
Author

isocroft commented Oct 22, 2025

/* @USAGE: */
useObserveDOMMutations((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation.type === "childList") {
        console.log("target id = ", mutation.target.id);
    }
  });
}, { childList: true, subtree: true });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment