Chrome MutationObserver pour le nouveau paragraphe du texte

Je n'ai pas encore vraiment compris comment utiliser mutationObserver, mais ce que j'ai actuellement semble avoir un certain droit … J'aimerais faire une action chaque fois que la nouvelle étiquette p apparaît dans le code. Voici mon code jusqu'à présent:

 var target = $('p'); var observer = new WebKitMutationObserver(function(mutations) { mutations.forEach(function(mutation) { chrome.storage.sync.get({ getInjection: true }, function(getInject) { var getInjectionState = getInject.getInjection; if(getInjectionState == true) { arrayOfP = $("p").text(); chrome.runtime.sendMessage(arrayOfP, manageResponse); } }); }); }); observer.observe(target[0], { attributes: true, childList: true, characterData: true }); 

Ce code se trouve dans un script de contenu dans une extension chrome. Pourquoi ne fonctionne-t-il pas? Toute aide serait appréciée. Merci!

  1. Observer.observe devrait observer l'élément parent / conteneur auquel les nouveaux éléments p sont ajoutés ou document.body .

    • observer.observe($('.some-container-selector')[0], .....
    • observer.observe(document.body, .....
  2. Dans le rappel, vous devez vérifier si le nœud ajouté est en fait p :

     mutations.forEach(function(mutation) { Array.prototype.forEach.call(mutation.addedNodes, function(node) { if (node.nodeType != 1) return; // only process Node.ELEMENT_NODE if (node.localName != 'p') { // not P but might be DIV with P inside node = node.querySelector('p'); if (!node) return; } // now we have our P node console.log("Got P!", node); }); }); 


Comme alternative, voici une fonction que je réutilise depuis plusieurs années, avec une boucle de virage plus rapide, mais beaucoup plus rapide:

 function setMutationHandler(baseNode, selector, cb) { new MutationObserver(function(mutations) { for (var i=0, ml=mutations.length, m; (i<ml) && (m=mutations[i]); i++) for (var j=0, nodes=m.addedNodes, nl=nodes.length, n; (j<nl) && (n=nodes[j]); j++) if (n.nodeType == 1) if ((n = n.matches(selector) ? [n] : n.querySelectorAll(selector)) && n.length) if (!cb.call(this, [].slice.call(n))) return; }).observe(baseNode, {subtree:true, childList:true}); } 

Utilisation (ici, le rappel ne recevra que des éléments p sous .some-container-class ):

 setMutationHandler(document, '.some-container-class p', function(nodes) { nodes.forEach(function(node) { console.log("Got node", node); // do something }); //this.disconnect(); // disconnect the observer, useful for one-time jobs //return true; // continue enumerating current batch of mutations }); 

La dernière for-loop se compare rarement aux boucles de setMutationHandler, donc il peut être remplacé par un [].forEach.call(nodes, ... ou Array.prototype.forEach.call(nodes, .... ou .each wrapper avec .each .

PPS pour Chrome pré-34, cela est nécessaire au début du script:

 if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.webkitMatchesSelector;