2016-06-22 2 views
1

Я пишу простую учетную запись, которая автоматически скрывает сообщение Facebook, если содержит определенный список слов. Основная функциональность работает, но мой MutationObserver, кажется, не читает classNamemutation.addedNodes должным образом. Я прохожу через mutation.addedNodes и проверяю, имеет ли какой-либо из этих элементов класс userContentWrapper, но результат этого теста всегда неверен - даже если у элемента есть класс.Получение имени класса добавленного узла DOM (mutationObserver)

var startObserver = function() {   
    var observer = new MutationObserver(function(mutations) {   
     mutations.forEach(function(mutation) {    
      var added = mutation.addedNodes;    
      for (var i = 0; i < added.length; i++) {     
       if (/\buserContentWrapper\b/.test(added[i].className)) { 
        processFilter(added[i]); 
       } 
      } 
     });   
    });  
    var obj = {childList: true, subtree: true, attributes: true}; 
    observer.observe(document.documentElement, obj); 
}; 

Я могу только предположить, что наблюдатель анализирует добавленный узел, прежде чем он полностью сформирован со всеми атрибутами на месте. Как заставить наблюдателя ждать обработки узла до тех пор, пока он не будет полностью завершен? Или я не понимаю проблему?

Заранее спасибо ...

ответ

3

Некоторые из добавленных узлов являются контейнерами, так что вы должны копать глубже:

var startObserver = function() { 
    var observer = new MutationObserver(function(mutations) { 
     for (var m=0; m < mutations.length; m++) { 
      var added = mutations[m].addedNodes; 
      for (var i = 0; i < added.length; i++) { 
       var node = added[i]; 
       if (node.nodeType != 1) { // not Node.ELEMENT_NODE 
        continue; 
       } 
       if (/\buserContentWrapper\b/.test(node.className)) { 
        processFilter(node); 
       } else if (node.children.length) { 
        var nodes = node.getElementsByTagName('userContentWrapper'); 
        for (var j = 0; j < nodes.length; j++) { 
         processFilter(nodes[j]); 
        } 
       } 
      } 
     }); 
    }); 
    observer.observe(document, {childList: true, subtree: true}); 
}; 

MutationObserver обратного вызова выполняется как microtask, который блокирует DOM и движок JS, так он должен быть чрезвычайно быстро, особенно на сложном сайте, таком как facebook, который генерирует много мутаций DOM.

Это может быть протестировано в devtools (F12 ключ) профилировщик/панели временной шкалы.

Если вы хотите, чтобы свести к минимуму неблагоприятных последствий использования MutationObserver, отложите крупную партию изменений в следующую задачу события:

var startObserver = function() { 
    var observer = new MutationObserver(function handler(mutations, postponed) { 
     if (mutations.length > 100 && !postponed) { 
      setTimeout(function() { handler(mutations, true) }, 0); 
      return; 
     } 
     for (var m=0; m < mutations.length; m++) { 
      var added = mutations[m].addedNodes; 
      for (var i = 0; i < added.length; i++) { 
       var node = added[i]; 
       if (node.nodeType != 1) { // not Node.ELEMENT_NODE 
        continue; 
       } 
       if (/\buserContentWrapper\b/.test(node.className)) { 
        processFilter(node); 
       } else if (node.children.length) { 
        var nodes = node.getElementsByTagName('userContentWrapper'); 
        for (var j = 0; j < nodes.length; j++) { 
         processFilter(nodes[j]); 
        } 
       } 
      } 
     }); 
    }); 
    observer.observe(document, {childList: true, subtree: true}); 
}; 
+0

ли не добавлять '' childList' и subtree' с параметрами наблюдения поковыряться автоматически ? – Cliff

+0

Это не * расширение *, что было добавлено. Например, 'someNode.appendChild (anotherNodeWith1000children)' не будет расширяться, потому что это всего лишь одна операция. – wOxxOm

+0

Да, я подумал, что так работает «childList», а затем «поддерево» будет автоматически искать все потомки. Что же такое '' поддерево', то? – Cliff

Смежные вопросы