Skip to main content

Як працює MutationObserver?

MutationObserver - це вбудований у браузер API, який дозволяє стежити за змінами в DOM: додаванням, видаленням, зміною атрибутів або тексту елементів, і реагувати на це в реальному часі.

Це потужна альтернатива старим подіям на кшталт DOMSubtreeModified (які застаріли й гальмували сторінку).


Визначення

MutationObserver - це спеціальний об'єкт, який "спостерігає" за елементом і повідомляє, коли в ньому щось змінилося (структура, атрибути, текст тощо).

Він працює асинхронно, не блокує інтерфейс і викликає колбек, коли у спостережуваному вузлі відбулися зміни.


1. Базовий приклад

javascript
// Створюємо спостерігач 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. Приклад роботи "наживо"

javascript
<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()

javascript
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. Зупинка спостереження

Щоб перестати стежити:

javascript
observer.disconnect();

Щоб тимчасово призупинити і знову ввімкнути:

javascript
observer.takeRecords(); // повертає накопичені зміни observer.observe(...); // можна ввімкнути знову

6. Приклад: стежимо за динамічними вставками

Дуже поширений кейс - ловити нові елементи, додані JS-фреймворком (наприклад, React, Vue, або чужим скриптом):

javascript
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. Приклад: автоматична реакція на зміну класу

javascript
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.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.