Mutation Observer 不检测通过innerHTML、appendChild 添加的节点

Posted

技术标签:

【中文标题】Mutation Observer 不检测通过innerHTML、appendChild 添加的节点【英文标题】:Mutation Observer does not detect nodes added through innerHTML, appendChild 【发布时间】:2018-07-15 17:35:33 【问题描述】:

当我们尝试使用 appendChild 或 innerhtml 在 DOM 中添加嵌套节点时,嵌套节点不会出现在突变的 addedNodes 中。

初始 HTML 设置:

<html>
    <body>
        <div id="container">
        </div>
    </body>
</html>

这是我的 Mutation Observer 代码:

var observer = new MutationObserver(function(mutations) 
  for (var i = 0; i < mutations.length; i++) 
    var mutation = mutations[i];
    switch(mutation.type) 
      case 'childList':
        console.log(mutation.addedNodes);
      break;
      default:

    
  
);

observer.observe(document, 
    childList: true,
    subtree: true,
    attributes: true,
    characterData: true
);

如果我现在在 div 中使用嵌套的 img 节点执行 appendChild,

var img = document.createElement('img');
img.setAttribute("src", "http://img.zohostatic.com/discussions/v1/images/defaultPhoto.png");
var div = document.createElement('div');
div.appendChild(img);
var container = document.getElementById("container");
container.appendChild(div);

Mutation Observer 只记录附加到容器的 div,但不记录 img 作为变化中的 addedNode。

这是一个有效的 JSFiddle:https://jsfiddle.net/aedhefhn/

有解决办法吗?

【问题讨论】:

【参考方案1】:

这是预期的行为。 div 是附加的所有内容,它恰好有一些孩子。不过,您当然可以自己从.addedNodes 遍历其子节点。 .addedNodes 只是一个节点数组,因此您可以递归地遍历每个项目以获取所有子项。

【讨论】:

我同意。但是,如果我们有一个带有 的 DOM 结构,为什么 Mutation Observer 在 addedNodes 中有图像?它不应该以同样的方式行事。因为,无论是否以编程方式,DOM 看起来都一样 MutationObserver 的目标是列出已执行的变异操作,而不是显式跟踪添加的所有内容。您的观察者正在收听document 的子树。对文档执行的唯一突变是附加div。当图像附加到 div 时,没有附加 div,因此当时没有附加到 div 的突变观察者会为图像执行附加操作。

以上是关于Mutation Observer 不检测通过innerHTML、appendChild 添加的节点的主要内容,如果未能解决你的问题,请参考以下文章