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

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

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

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

Вы используете его так же, как .each function

$(".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.

Ответ 6

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

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

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