Наиболее эффективный метод обнаружения / мониторинга изменений DOM?

StackOverflow https://stackoverflow.com/questions/2457043

Вопрос

Мне нужен эффективный механизм для обнаружения изменений в DOM.Предпочтительно кроссбраузерный, но если есть какие-либо эффективные средства, которые не кроссбраузерный, я могу реализовать их с помощью безотказного кроссбраузерного метода.

В частности, мне нужно обнаружить изменения, которые повлияли бы на текст на странице, поэтому потребуются любые новые, удаленные или измененные элементы или изменения во внутреннем тексте (innerHTML).

У меня нет контроля над вносимыми изменениями (они могут быть связаны со сторонними включениями javascript и т.д.), Поэтому к этому нельзя подходить с этой точки зрения - мне нужно как-то "отслеживать" изменения.

В настоящее время я внедрил метод "quick'n'dirty", который проверяет body.innerHTML.length с интервалами.Это, конечно, не приведет к обнаружению изменений, которые приводят к возврату той же длины, но в данном случае "достаточно хорошо" - шансы на то, что это произойдет, чрезвычайно малы, и в этом проекте неспособность обнаружить изменение не приведет к потере данных.

Проблема с body.innerHTML.length дело в том, что это дорого.Это может занять от 1 до 5 миллисекунд на быстро браузер, и это может сильно затруднить работу - я также имею дело с большим количеством iframes, и все это суммируется.Я почти уверен, что дороговизна этого заключается в том, что текст innerHTML не хранится браузерами статически и должен вычисляться из DOM при каждом его чтении.

Типы ответов, которые я ищу, могут быть любыми - от "точных" (например, event) до "достаточно хороших" - возможно, что-то столь же "быстрое и грязное", как метод innerHTML.length, но это выполняется быстрее.

Редактировать:Я должен также отметить, что, хотя было бы "неплохо" определить точный элемент, который был изменен, это не является абсолютной необходимостью - просто тот факт, что был Любой перемен было бы достаточно.Надеюсь, это расширит круг откликов людей.Я собираюсь исследовать события мутации, но мне все еще нужен запасной вариант для поддержки IE, поэтому любые необычные, креативные, нестандартные идеи были бы очень кстати.

Это было полезно?

Решение

http://www.quirksmode.org/js/events/DOMtree.html

jQuery теперь поддерживает способ прикрепления событий к существующим и будущим элементам, соответствующим селектору: http://docs.jquery.com/Events/live#typefn

Еще одна интересная находка - http://james.padolsey.com/javascript/monitoring-dom-properties/

Другие советы

Чтобы обновить это, стандарт DOM4 устраняет события мутации и заменяет их наблюдателями мутации: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

События мутации это рекомендация W3 о том, что вы ищете..

Не уверен, поддерживаются ли они повсюду..(IE, скорее всего, не будет их поддерживать ..)

Вы могли бы попробовать использовать события DOMNodeInserted и DOMNodeRemoved.Согласно Quirksmode, они работают в большинстве браузеров, за заметным исключением IE...

http://www.quirksmode.org/dom/events/index.html

Недавно я написал плагин, который делает именно это - jquery.инициализировать

Вы используете его так же, как .each функция

$(".some-element").initialize( function(){
    $(this).css("color", "blue"); 
});

Отличие от .each есть - в данном случае требуется ваш селектор .some-element и ждите новых элементов с этим селектором в будущем, если такой элемент будет добавлен, он тоже будет инициализирован.

В нашем случае для инициализации функции просто измените цвет элемента на синий.Итак, если мы добавим новый элемент (неважно, с помощью ajax или даже инспектора F12 или чего-то еще), например:

$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!

Плагин инициализирует его мгновенно.Также плагин гарантирует, что один элемент инициализируется только один раз.Итак, если вы добавите элемент, то .deatch() извлеките его из тела, а затем добавьте его снова, он больше не будет инициализирован.

$("<div/>").addClass('some-element').appendTo("body").detach()
    .appendTo(".some-container");
//initialized only once

Плагин основан на MutationObserver - он будет работать на IE9 и 10 с зависимостями, как подробно описано на страница readme.

jQuery Мутировать делает ли это тоже, по умолчанию он поддерживает как height, width, scrollHeight и т.д...но он также может быть расширен с помощью небольшого количества дополнительного кода для добавления новых событий, таких как просмотр, изменился ли текст и т.д...

http://www.jqui.net/jquery-projects/jquery-mutate-official/

Надеюсь, это поможет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top