【发布时间】:2018-08-22 03:06:01
【问题描述】:
我的代码的简化版:
<div id="d">text<br><hr>text</div>
<script>
// Called when DOM changes.
function mutationCallback(mutations) {
// assert(mutations.length === 3);
var insertImg = mutations[0];
console.log(insertImg.previousSibling.parentNode); // Null!
console.log(insertImg.nextSibling.parentNode); // Null!
// Can't determine where img was inserted!
}
// Setup
var div = document.getElementById('d');
var br = div.childNodes[1];
var hr = div.childNodes[2];
var observer = new MutationObserver(mutationCallback);
observer.observe(div, {childList: true, subtree: true});
// Trigger DOM Changes.
var img = document.createElement('img');
div.insertBefore(img, hr);
div.removeChild(hr);
div.removeChild(br); // mutationCallback() is first called after this line.
</script>
我正在使用 Mutation Observers 来捕获 DOM 更改,以便在另一个文档实例发生更改时更新一个文档实例。因为在 的前一个和下一个兄弟元素被删除之后才会调用突变观察函数,因此 mutationCallback 函数无法判断它是在哪里插入的。在 Chrome、FF 和 IE11 中重现。
另一种方法是遍历整个文档以查找更改,但这会抵消使用 Mutation Observers 的性能优势。
【问题讨论】:
-
为什么要以
.parentNode开头?mutations[0].target给了p和mutations[0].removedNodes[0]给你x,然后分开,因为它是一个单独的突变,mutations[1].target给div和mutations[1].removedNodes[0]给你p。这些信息足以重建发生的事情。 -
我正在将更改从一个文档克隆到另一个文档。第一个文档中的操作可以以任何顺序发生。所以我不能简单地将mutations[1].target 硬编码到我的解决方案中。
-
完全可以,但我是说您需要将
mutations数组中的每个项目完全重播到您的另一个文档中,每个mutations项目都会告诉您哪个节点发生了变化以及哪些信息关于它发生了变化,因此您通常不需要更多信息。 -
除此之外,如果您要删除一个节点,您通常不会关心其中的内容会发生什么。 “删除孙子,然后删除子”的情况甚至不应该发生......但如果确实发生了,并且您正在克隆更改,那么“删除孙子”不会影响生成的文档,所以它应该是可忽略的.
-
@loganfsmyth:这是我最初的假设,但它不能那样工作。当我收到第一个突变时,我看到 x 已从 p 节点中删除,但当时 p 节点已经没有父节点。所以信息不够。发生这种情况时,我不知道查看突变[1],因为我不知道 DOM 更改发生的顺序。
标签: javascript dom mutation-observers