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 添加的节点的主要内容,如果未能解决你的问题,请参考以下文章

javascript Mutation Observer Snippet

理解 Mutation Observer

Mutation Observer

用于创建新元素的 Mutation Observer

断开 Mutation Observer 与回调函数的连接

变异测试(mutation testing):一种评估测试用例集错误检测能力的方法