Почему код MutationObserver не работает в Chrome 30?

Из http://updates.html5rocks.com/2012/02/Detect-DOM-changes-with-Mutation-Observers Я получил следующий код:

var insertedNodes = [];
var observer = new WebKitMutationObserver(function(mutations) {
 alert('run');
 mutations.forEach(function(mutation) {
   for (var i = 0; i < mutation.addedNodes.length; i++)
     insertedNodes.push(mutation.addedNodes[i]);
 })
});
observer.observe(document, { childList: true });
console.log(insertedNodes);

var divElement = document.createElement('div');
divElement.innerHTML = 'div element';
document.querySelector('body').appendChild(divElement);

jsFiddle: http://jsfiddle.net/cUNH9

Как видите, мы должны увидеть предупреждение, потому что элемент div вставлен в DOM. Но, похоже, коды MutationObserver не запускаются. Как я могу успешно запустить код MutationObserver?


person weilou    schedule 03.10.2013    source источник
comment
Да, если вы соблюдаете document.body, это сработает.   -  person PSL    schedule 03.10.2013
comment
@plalx Я пробовал и new MutationObserver, и new WebKitMutationObserver. У них одинаковый результат.   -  person weilou    schedule 03.10.2013
comment
@weilou, не используйте document.querySelector('body'), просто используйте document.body.   -  person plalx    schedule 03.10.2013
comment
@weilou Смотрите мой ответ ... Он также будет работать с документом.   -  person PSL    schedule 03.10.2013


Ответы (1)


Добавьте также опцию subTree, она должна работать, вы хотите отслеживать не только дочерние элементы документа ( head/body), но и его потомков. (И по этой причине при установке document.body все работает).

observer.observe(document, {
    attributes: true,
    childList: true,
    characterData: true,
    subtree:true
});

Скрипка

Из документации

subtree: установите значение true, если необходимо наблюдать за мутациями не только целевого объекта, но и его потомков.

Итак, то, что вы добавляете, является потомком document, а не его дочерним элементом (или прямым потомком). Это дочерний элемент body (и именно поэтому простое упоминание childList и использование document.body работает). Вам нужно упомянуть subTree, если вы хотите отслеживать изменения глубоко.

Также см. примечание:

ПРИМЕЧАНИЕ. По крайней мере для параметров childList, attribute или characterData должно быть установлено значение true. В противном случае выдается ошибка «Была указана недопустимая или недопустимая строка».

person PSL    schedule 03.10.2013
comment
@plalx Нет. Поддерево требуется, если он хочет также отслеживать глубоко в теле, например, если он хочет добавить еще один div внутри этого div. - person PSL; 03.10.2013
comment
@plalx проверьте этот пример, удалите поддерево и попробуйте. jsfiddle.net/9wtDc - person PSL; 03.10.2013
comment
@PSL, верно, мой плохой;) - person plalx; 03.10.2013
comment
@PSL Это не работает в Firefox. Есть ли альтернатива? - person cainhs; 09.11.2016
comment
@cainhs MDN говорит, что он также должен работать с Firefox. - person PSL; 10.11.2016
comment
@PS Я нашел проблему. Я не должен отслеживать документ.тело в Firefox, так как DOM не готов. (т.е. он пуст) во время загрузки страницы. Вместо этого создайте основной div в теле и наблюдайте за ним. Интересно, почему Firefox ведет себя иначе, чем Chrome и IE. - person cainhs; 17.11.2016