简体   繁体   English

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

[英]ChildNodes seemingly not existing in DOM while using MutationObserver

I am trying to use MutationObserver to observe changes in the DOM but it seems like I can't access the "grand"-children nodes.我正在尝试使用 MutationObserver 来观察 DOM 中的变化,但似乎我无法访问“大”子节点。 I have configured the observer with subtree and childList values.我已经为观察者配置了子树和 childList 值。 As I understand, it is not possible to get the entire DOM-tree of added childLists or changes with the MutationObserver, all it does is observe the changes.据我了解,不可能通过 MutationObserver 获取添加的子列表或更改的整个 DOM 树,它所做的只是观察更改。 Instead you are supposed to use getElementById.相反,您应该使用 getElementById。

I've tried using getElementById to find the relevant "parent"-node in the DOM after the change is observed, and then crawl all the childNodes.在观察到更改后,我尝试使用 getElementById 在 DOM 中找到相关的“父”节点,然后抓取所有子节点。 Although I still get no hits on the childNodes.尽管我仍然没有对 childNodes 进行任何点击。

I assume the "parent"-node is inserted onto the DOM first, and the childNodes are then inserted on to the "parent"-node after the fact, though these events are not triggered in the observer for some reason.我假设首先将“父”节点插入到 DOM 中,然后在事后将子节点插入到“父”节点中,尽管由于某种原因这些事件没有在观察者中触发。

I suspect I might need to update the target of the MutationObserver as I observe the changes, and then continuously use getElementById and crawl these nodes.我怀疑我可能需要在观察更改时更新 MutationObserver 的目标,然后不断使用 getElementById 并爬取这些节点。

Any idea on why these childNodes are not observable, and/or how to approach the solution to this?关于为什么这些子节点不可观察,和/或如何解决这个问题的任何想法?

Best regards.最好的祝福。

Code to MutationObserver 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)
}

Let's investigate by logging the added nodes that belong to #qc-cmp2-container element:让我们通过记录属于#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});

We'll see several separate calls:我们将看到几个单独的调用:

  1. The main #qc-cmp2-container and its empty child主要的 #qc-cmp2-container 及其空子容器
  2. An inner div with a lot of child elements and text一个包含大量子元素和文本的内部 div
  3. Two additional inner elements are added添加了两个额外的内部元素

The most resource-effective solution is to wait for the parent using the super fast getElementById check and then switch to observing the parent:最节省资源的解决方案是使用超快速 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 });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM