Як працює MutationObserver?
MutationObserver - це вбудований у браузер API, який дозволяє стежити за змінами в DOM: додаванням, видаленням, зміною атрибутів або тексту елементів, і реагувати на це в реальному часі.
Це потужна альтернатива старим подіям на кшталт DOMSubtreeModified (які застаріли й гальмували сторінку).
Визначення
MutationObserver- це спеціальний об'єкт, який "спостерігає" за елементом і повідомляє, коли в ньому щось змінилося (структура, атрибути, текст тощо).
Він працює асинхронно, не блокує інтерфейс і викликає колбек, коли у спостережуваному вузлі відбулися зміни.
1. Базовий приклад
// Створюємо спостерігач
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
console.log('Тип зміни:', mutation.type);
});
});
// Елемент, за яким будемо стежити
const target = document.querySelector('#app');
// Налаштування спостереження
observer.observe(target, {
childList: true, // стежити за додаванням/видаленням дочірніх елементів
attributes: true, // стежити за зміною атрибутів
subtree: true // стежити за всім усередині елемента
});Тепер, якщо ти додаси в #app новий елемент або зміниш атрибут, у консолі з'явиться повідомлення про тип зміни.
2. Приклад роботи "наживо"
<div id="box">Привіт!</div>
<button id="btn">Змінити</button>
<script>
const box = document.getElementById('box');
const btn = document.getElementById('btn');
const observer = new MutationObserver((mutations) => {
mutations.forEach(m => console.log(m));
});
observer.observe(box, { childList: true, attributes: true, characterData: true });
btn.addEventListener('click', () => {
box.textContent = 'Текст змінено!';
box.setAttribute('data-status', 'updated');
});
</script>При кліку в консолі з'являться об'єкти MutationRecord, у яких буде інформація про:
- тип зміни (
attributes,childList,characterData); - який атрибут змінився;
- старе і нове значення (якщо ввімкнено).
3. Налаштування observe()
observer.observe(target, {
childList: true, // додавання/видалення дочірніх елементів
attributes: true, // зміна атрибутів
characterData: true, // зміна тексту всередині вузлів
subtree: true, // стежити за нащадками (усе дерево)
attributeFilter: ['class', 'style'], // стежити лише за цими атрибутами
attributeOldValue: true, // зберігати старе значення атрибутів
characterDataOldValue: true // зберігати старе значення тексту
});4. Що містить MutationRecord
Кожен елемент масиву mutations - це об'єкт MutationRecord із властивостями:
| Властивість | Опис |
|---|---|
type | тип зміни (attributes, childList, characterData) |
target | елемент, де відбулася зміна |
addedNodes | додані елементи |
removedNodes | видалені елементи |
attributeName | ім'я зміненого атрибута |
oldValue | старе значення атрибута або тексту |
5. Зупинка спостереження
Щоб перестати стежити:
observer.disconnect();Щоб тимчасово призупинити і знову ввімкнути:
observer.takeRecords(); // повертає накопичені зміни
observer.observe(...); // можна ввімкнути знову6. Приклад: стежимо за динамічними вставками
Дуже поширений кейс - ловити нові елементи, додані JS-фреймворком (наприклад, React, Vue, або чужим скриптом):
const container = document.querySelector('#feed');
const observer = new MutationObserver((mutations) => {
mutations.forEach(m => {
m.addedNodes.forEach(node => {
if (node.nodeType === 1 && node.matches('.post')) {
console.log('Новий пост додано:', node.textContent);
}
});
});
});
observer.observe(container, { childList: true, subtree: true });Тепер при динамічному додаванні <div class="post">...</div> JS миттєво відреагує.
7. Приклад: автоматична реакція на зміну класу
const box = document.querySelector('#box');
const observer = new MutationObserver((entries) => {
for (const mutation of entries) {
if (mutation.attributeName === 'class') {
console.log('Клас змінився на:', box.className);
}
}
});
observer.observe(box, { attributes: true });Це зручно для відстеження зміни стану, наприклад під час анімацій або toggle-ефектів.
8. Продуктивність
MutationObserverпрацює асинхронно: зміни "пакуються" і приходять одним батчем, а не на кожен піксель чи символ.- Це робить його дуже продуктивним навіть за великої кількості спостережень.
- Але не зловживай
subtree: trueна всьомуdocument- це може бути дорого.
Підсумок
| Що робить | MutationObserver |
|---|---|
| Відстежує | Зміни в DOM (атрибути, текст, додавання/видалення елементів) |
| Заміна для | Старих подій DOMNodeInserted, DOMSubtreeModified |
| Працює | Асинхронно, через чергу мікротасків |
| Використовується для | Динамічного UI, інтеграцій, спостереження за React/Vue, анімацій, кастомних компонентів |
| Керування | observe(), disconnect(), takeRecords() |
Запам'ятай просто:
MutationObserver- це "охоронець DOM": стежить за змінами в дереві й повідомляє, що, де і коли змінилося, без постійних перевірок чи подійscroll.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.