是否有可能以及如何从MutationObserver获取变异节点的每个子节点(不仅仅是直接子节点)的报告?
请看下面的代码:
($ => {
$(() => {
var $body = $(document.body).html('');
(new MutationObserver(function (records) {
for (var record of records) {
console.log('----------');
for (var node of record.addedNodes) {
if (node instanceof Element) {
console.log('addition', node.tagName, node.childNodes.length);
}
}
for (var node of record.removedNodes) {
if (node instanceof Element) {
console.log('removal', node.tagName, node.childNodes.length);
}
}
}
})).observe(document.body, {
childList: true,
subtree: true
});
$body.append('<a/>');
$body.find('a').wrap('<span/>');
$body.append('<div><b/></div>');
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
首先,为了清晰起见,我从身体上移除了所有东西。然后我附上一个MutationObserver
,它会报告添加和删除,并报告子节点数。
如您所见,我将<a/>
元素附加到正文,然后将其包装在<span/>
中。之后,我在<b/>
元素中添加<div/>
元素。如果你看一下控制台,你可能会看到以下输出:
----------
addition A 0
----------
addition SPAN 1
----------
removal A 0
----------
addition A 0
----------
addition DIV 1
因此,第一个追加被正确报告为0个子节点。
然后,在wrap()
调用期间,添加了一个新的<span/>
元素,删除了<a/>
元素,然后将其添加回(此时在范围内)。所有内容都被正确报告,除了(在报告时)人们希望<span/>
元素为空,但它已经有一个子节点 - 包裹<a/>
。
这实际上是根据规范指定此类突变排队然后异步启动 ,即使回调的执行是同步。这是故意的,因为听众会被事件轰炸并严重损害表现。
此外,最终添加报告添加的<div/>
元素(已包含1个子节点),但不报告其子<b/>
元素。
再次,这可能是故意的,因为为触发基本添加到DOM的每个节点的添加变异将是一场性能噩梦。
作为我正在处理的插件的一部分,我需要“知道”有关DOM中添加或删除的每个最终元素节点,即使它是子树的一部分。
我最初的解决方案是在添加/删除节点时遍历所有子节点,并将它们视为添加/删除。不幸的是,这是不可行的,因为在调用监听器时,DOM的状态已经发生了变化,如addition SPAN 1
所示。
那么,您是否知道任何“功能”或方法可以让我报告/确定,至少在我的代码的上下文中,这些子节点是否已经与其父节点一起被添加到节点中? / p>