Home > Net >  Apply a CSS selector on all removed nodes with MutationObserver HTML5 API
Apply a CSS selector on all removed nodes with MutationObserver HTML5 API

Time:08-05

Below is how I get all removed nodes from the DOM that have a class in the list selected_classes. It works but it's rather complicated (and some corner cases might be forgotten?).

Is there a more general way to filter removed nodes from the DOM by CSS selectors? Pseudo-code:

new MutationObserver(mut => {
    removed_nodes = removed_nodes(mut);
    console.log(removed_nodes.querySelectorAll('.hello'));
    console.log(removed_nodes.querySelectorAll('.myclass #a'));
}).observe(document.querySelector("html"), { childList: true, subtree: true });

Here is the working code, only for classes:

selected_classes = {"banana": 0, "hello": 0};

new MutationObserver(mut => {
    for (m of mut) {
        for (n of m.removedNodes) {
            if (n.classList)   // text node don't have a classList!
                for (c of n.classList.values())
                    if (c in selected_classes)
                        console.log("selected_classes found:", n);
            if (n.childNodes)
                for (n2 of n.childNodes.values())
                    if (n2.classList)
                        for (c of n2.classList.values())
                            if (c in selected_classes)
                                console.log("selected_classes found:", n2);                
        }
    }
}).observe(document.querySelector("html"), { childList: true, subtree: true });

document.getElementById("c").onclick = () => { document.getElementById("b").remove(); }
<div id="a">a</div>
<div id="b" >b
<div id="b1">b1</div>
<div id="b2" >b2 (class hello)</div>
</div>
<div id="c">Click to remove b</div>

CodePudding user response:

Create a CSS selector from selected_classes and use that with .matches() and .querySelectorAll() to get matching notes

const selector = ".banana, .hello";

new MutationObserver(mut => {
 
  for (m of mut) {
    for (n of m.removedNodes) {
      if (n.matches(selector)) {
        console.log("direct match", n);
      }

      n.querySelectorAll(selector)
         .forEach(c => console.log("child (any depth)", c));
    }
  }
}).observe(document.querySelector("html"), { childList: true, subtree: true });

document.getElementById("c").onclick = () => { document.getElementById("b").remove(); }
<div id="a">a</div>
<div id="b" >b
  <div id="b1">b1</div>
  <div id="b2" >b2 (class hello)</div>
  <div>
    <div>
      <div >Banana</div>
    </div>
  </div>
</div>
<div id="c">Click to remove b</div>

  • Related