Blog. Just Blog

Отслеживание изменений в DOM через Mutation Events и MutationObserver

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Отслеживание изменений в DOM через Mutation Events и MutationObserver
Отслеживание изменений в DOM через Mutation Events и MutationObserver

Время статичных web-страниц уже давно прошло, теперь немалая часть контента подгружается динамически уже после загрузки основной страницы. Соответственно, эти данные недоступны для скриптов, отслеживающих загрузку через события типа onload или DOMContentLoaded. Может возникнуть вопрос: а зачем вообще это отслеживать? Ну, например, чтобы при помощи браузерных расширений и пользовательских скриптов удалять со страниц динамически подгружаемую рекламу, которую другими способами не заблокировать. К счастью, для отслеживания любых изменений, вносимых в структуру DOM, есть как минимум два инструмента. Речь идет о событиях Mutation Events и интерфейсе MutationObserver.

Начнем с Mutation Events. Это была первая технология, представленная разработчиками браузеров, позволяющая web-мастерам отслеживать изменения в DOM и каким-то образом реагировать на них. Это набор событий, срабатывающих при добавлении или удалении элемента, изменении атрибутов, содержимого и т.п. Использовать их можно как и любые другие события. Приложению достаточно выбрать отслеживаемый элемент и повесить на него обработчик соответствующего события или событий, в зависимости от поставленной задачи.
  1. <script type="text/javascript">
  2. // Элемент, в котором отслеживаются изменения
  3. var el=document.getElementById('test');
  4. // Добавить обработку события
  5. el.addEventListener("DOMNodeInserted",
  6.     function(e) {
  7.         // Добавляемый элемент
  8.         var node=e.srcElement;
  9.         // Родительский элемент
  10.         var target=e.relatedNode;
  11.         ...
  12.     },
  13.     false
  14. );
  15. </script>
Таким образом можно получить всю информацию как о добавляемом элементе, так и о целевом элементе, куда он будет добавлен. Имея эти данные, в обработчике можно, например, удалить добавленный элемент, изменить его содержимое или выполнить другие необходимые действия.

При кажущейся простоте использования, события Mutation Events остаются событиями, поэтому вызываются синхронно. В связи с этим они имеют большие проблемы с производительностью, особенно в случае, когда меняется много элементов. Более того, если обработчик попытается самостоятельно добавить какой-нибудь элемент к целевому, то это также повлечет за собой срабатывания этого же обработчика, что в конечном итоге может привести к непредсказуемым результатам. Поэтому буквально через год после релиза технология Mutation Events получила статус "устаревшей", да и поддержка этих событий браузерами оставляет желать лучшего.

Следующим шагом развития технологии отслеживания изменений на странице стало появление браузерного API DOM MutationObserver, который должен был избавиться от недостатков Mutation Events. Пользоваться DOM MutationObserver не намного сложнее, чем событиями. Выбираем элемент, в котором будут отслеживаться изменения, создаем объект наблюдателя и задаем конфигурацию, в которой прописываем, какие изменения нас интересуют. Это может быть изменение атрибутов, содержимого, добавление или удаление элементов.
  1. // Элемент, в котором отслеживаются изменения
  2. var el=document.getElementById('test');
  3. // Создать наблюдателя
  4. var observer = new MutationObserver(function(mutations) {
  5.     for (var i in mutations) {
  6.         // Запись о произошедших изменениях
  7.         var mutation=mutations[i];
  8.         ...
  9.     };
  10. });
  11.  
  12. // Запустить наблюдателя изменений
  13. observer.observe(el, {
  14.     attributestrue,
  15.     childListtrue,
  16.     subtreetrue,
  17.     characterDatatrue
  18. });
Наблюдателю передается список записей MutationRecord, в которых содержится информация о произошедших изменениях. Все есть в документации, но вот наиболее интересные поля:
  • type - тип изменения, одно из возможных значений: "attributes" - изменен атрибут, "characterData" - изменены данные текстовых узлов, "childList" - добавлены или удалены дочерние элементы;
  • target - где произошло изменение: элемент для "attributes", текстовый узел для "characterData" или элемент для "childList";
  • addedNodes/removedNodes – список добавленных и удаленных элементов;
  • oldValue - предыдущее значение при изменении атрибута или текста.
В отличие от Mutation Events, функция наблюдателя сработает только тогда, когда выполнятся все скрипты и все изменения DOM полностью завершатся. Разные опции конфигурации наблюдателя предназначены для оптимизации, чтобы не тратить ресурсы на лишние вызовы.

Когда наблюдатель больше не нужен, его можно отключить методом disconnect(). Но даже после отключения наблюдателя, последние необработанные записи будут доступны через метод takeRecords().

Поделиться ссылкой ВКонтакте
Просмотров: 3554 | Комментариев: 2

Метки: JavaScript
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (01.09.2020 в 12:48):
Художник Вася Ложкин, фрагмент одной из его картин.
Petya (01.09.2020 в 12:42):
Что-то мне эти строгие дядьки в штатском напоминают. Откуда взяли?

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.17 сек. / MySQL: 2 (0.0084 сек.) / Память: 4.5 Mb
Наверх