使用 MutationObserver 时,DOM 中似乎不存在子节点

ChildNodes seemingly not existing in DOM while using MutationObserver

我正在尝试使用 MutationObserver 来观察 DOM 中的变化,但似乎我无法访问“大”子节点。我已经为观察者配置了子树和 childList 值。据我了解,不可能通过 MutationObserver 获得添加的子列表或更改的整个 DOM 树,它所做的只是观察更改。相反,您应该使用 getElementById。

我试过在观察到变化后使用getElementById在DOM中找到相关的“父”节点,然后爬取所有子节点。虽然我仍然没有在 childNodes 上点击。

我假设先将“父”节点插入到 DOM 上,然后再将子节点插入到“父”节点上,尽管这些事件不会在出于某种原因观察者。

我怀疑我可能需要在观察变化时更新 MutationObserver 的目标,然后继续使用 getElementById 并爬取这些节点。

关于为什么这些子节点不可观察的任何想法,and/or如何解决这个问题?

此致。

MutationObserver 的代码

function createObserver() {
    const documentBody = document.body;

    // callback function to execute when mutations are observed
    const observer = new MutationObserver(mutationRecords => {
        let addedNodes = []

        for (const mut of mutationRecords) {

            let arr = Array.prototype.slice.call(mut.addedNodes)
            arr = arr.filter(node => popupTagNames.includes(node.tagName)); // Keep only selected tags

            if (arr.length == 0) return; // don't keep empty

            addedNodes = addedNodes.concat(arr)

            let el = document.getElementById(addedNodes[0].id);

            // Crawler
            inspectNode(el)
        }


    })

    const config = { attributes: true, childList: true, subtree: true, characterData: true }
    observer.observe(documentBody, config)
}

让我们通过记录属于#qc-cmp2-container 元素的添加节点进行调查:

new MutationObserver(mutations => {
  const parent = document.getElementById('qc-cmp2-container');
  if (parent) console.log(...mutations.flatMap(m =>
    [...m.addedNodes].filter(n => parent.contains(n)).map(n => n.cloneNode(true))));
}).observe(document, {subtree: true, childList: true});

我们将看到几个单独的调用:

  1. 主要的 #qc-cmp2-container 及其空子容器
  2. 内部 div 有很多子元素和文本
  3. 添加了两个额外的内部元素

最 resource-effective 解决方案是使用超快速 getElementById 检查等待父级,然后切换到观察父级:

function waitForId(id, callback) {
  let el = document.getElementById(id);
  if (el) {
    callback(el);
  } else {
    new MutationObserver((mutations, observer) => {
      el = document.getElementById(id);
      if (el) {
        observer.disconnect();
        callback(el);
      }
    }).observe(document, { subtree: true, childList: true });
  }
}

waitForId('qc-cmp2-container', parent => {
  new MutationObserver((mutations, observer) => {
    // do something
  }).observe(parent, { subtree: true, childList: true });
});