Syntax
new MutationObserver(callback).observe(target, options)Examples
Watching for Added Child Elements
Reacting whenever new elements are added to a container.
const container = document.querySelector("#chatMessages");
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.addedNodes.length > 0) {
console.log("New message added, scrolling to bottom");
container.scrollTop = container.scrollHeight;
}
});
});
observer.observe(container, { childList: true });Watching for Attribute Changes
Reacting when a specific attribute changes on an element.
const target = document.querySelector("#statusBadge");
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.attributeName === "class") {
console.log("Class changed to:", target.className);
}
});
});
observer.observe(target, { attributes: true });
// Stop watching when no longer needed
// observer.disconnect();Best practices
- Use MutationObserver only when you genuinely need to react to DOM changes you do not control directly - if you control the code making the change, call your reaction logic directly instead
- Always call disconnect() when done observing, to avoid unnecessary background processing
- Be specific with the options object (childList, attributes, subtree) rather than observing everything, for better performance
- Avoid triggering more DOM mutations synchronously inside the callback in a way that could create an infinite mutation loop
At a glance
- Purpose
- Application logic and interaction
- File extension
- .js ยท .mjs
- Runs in
- Browsers and JavaScript runtimes
- Usually used with
- HTML, CSS and Web APIs
Specifications & further reading
Related JavaScript documentation
DOM Selection: querySelector(), getElementById()
These methods find elements in the DOM. getElementById() finds a single element by its unique id, generally the fastest option. querySelector() finds the first element matching any valid CSS selector, and querySelectorAll() returns all matching elements as a static NodeList.Creating and Modifying Elements
createElement() builds a new DOM element in memory, which can then be customized and inserted into the page with methods like appendChild() or append(). textContent sets plain text safely, while innerHTML parses and inserts HTML markup - which carries injection risks if the content includes untrusted user input.classList: add, remove, toggle, contains
The classList property provides a convenient API for managing an element's CSS classes without manually parsing the className string. add() and remove() add or remove one or more classes, toggle() switches a class on or off based on its current presence, and contains() checks whether a class is currently applied.IntersectionObserver
IntersectionObserver efficiently detects when an element enters or exits the viewport (or another container), without the performance cost of manually listening to scroll events and calculating positions. It is the standard tool for lazy-loading images, infinite scroll, and scroll-triggered animations.
These methods find elements in the DOM. getElementById() finds a single element by its unique id, generally the fastest option. querySelector() finds the first element matching any valid CSS selector, and querySelectorAll() returns all matching elements as a static NodeList.Creating and Modifying Elements
createElement() builds a new DOM element in memory, which can then be customized and inserted into the page with methods like appendChild() or append(). textContent sets plain text safely, while innerHTML parses and inserts HTML markup - which carries injection risks if the content includes untrusted user input.classList: add, remove, toggle, contains
The classList property provides a convenient API for managing an element's CSS classes without manually parsing the className string. add() and remove() add or remove one or more classes, toggle() switches a class on or off based on its current presence, and contains() checks whether a class is currently applied.IntersectionObserver
IntersectionObserver efficiently detects when an element enters or exits the viewport (or another container), without the performance cost of manually listening to scroll events and calculating positions. It is the standard tool for lazy-loading images, infinite scroll, and scroll-triggered animations.