23-04-26 17:08:33

Представь, что у тебя есть страница, где элементы могут изменяться динамически (например, чат, список задач или UI после API-запроса). Иногда нужно отследить эти изменения и выполнить код.
Раньше для этого использовали события вроде DOMNodeInserted, но они устарели и плохо работают.
MutationObserver — это современный и эффективный способ отслеживать изменения DOM.
Базовая идея
Ты создаешь «наблюдателя», говоришь ему:
И он вызывает callback, когда что-то меняется.
Пример
Допустим, мы хотим отследить добавление элементов в список:
<ul id="list"></ul>
const target = document.getElementById('list');
// создаем observer
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
console.log('Произошло изменение:', mutation);
}
});
// настраиваем, что именно отслеживать
observer.observe(target, {
childList: true // отслеживать добавление/удаление дочерних элементов
});
// добавим элемент
const li = document.createElement('li');
li.textContent = 'Новый элемент';
target.appendChild(li);
В консоли ты увидишь сообщение о том, что элемент добавлен.
Основные опции:
observer.observe(target, {
childList: true, // добавление/удаление элементов
attributes: true, // изменения атрибутов
characterData: true, // изменения текста
subtree: true // следить за всеми потомками
});
Примеры
Отслеживание изменения атрибутов
<div id="box"></div>
const box = document.getElementById('box');
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
console.log(`Атрибут ${mutation.attributeName} изменен`);
}
});
});
observer.observe(box, {
attributes: true
});
// меняем атрибут
box.setAttribute('class', 'active');
Отслеживание текста
<p id="text">Привет</p>
const textNode = document.getElementById('text').firstChild;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
console.log('Текст изменился:', mutation.target.data);
});
});
observer.observe(textNode, {
characterData: true
});
// изменение текста
textNode.data = 'Привет мир';
Если больше не нужно следить за изменениями — обязательно отключай observer:
observer.disconnect();
Это важно для:
Используй его, когда:
Не используй, если:
Следить за всем DOM
observer.observe(document.body, {
subtree: true,
childList: true
});
Это может сильно нагрузить браузер.
Забывать disconnect
Observer продолжает работать → утечки памяти.
Не фильтровать изменения
Всегда проверяй mutation.type, иначе будешь обрабатывать лишнее.
MutationObserver — мощный инструмент, который:
Но важно использовать его аккуратно, чтобы не убить производительность.