chrome MutationObserver for new paragraph text

前端 未结 1 1304
时光取名叫无心
时光取名叫无心 2020-12-21 22:48

I haven\'t really understood quite yet how to use the mutationObserver but what I currently have seems somewhat right... I\'d like to do an action every time new p

相关标签:
1条回答
  • 2020-12-21 23:44
    1. observer.observe should observe the parent/container element to which the new p elements are added or document.body.

      • observer.observe($('.some-container-selector')[0], .....
      • observer.observe(document.body, .....
    2. inside the callback you should check whether the added node is actually 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);
        });
      });
      


    As an alternative here's a function I reuse for several years, with an uglier but much faster for-loop:

    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}); 
    }
    

    Usage (here the callback would receive only p elements under .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
    });
    

    The last for-loop occurs quite rarely comparing to the setMutationHandler's loops so it may be replaced with a more concise [].forEach.call(nodes, ... or Array.prototype.forEach.call(nodes, .... or jQuery wrapper with .each.

    P.P.S. for Chrome pre-34 this is required somewhere at the start of the script:

    if (!Element.prototype.matches)
        Element.prototype.matches = Element.prototype.webkitMatchesSelector;
    
    0 讨论(0)
提交回复
热议问题