如何使MutationObserver也报告变异节点的子节点?

时间:2018-01-25 13:45:31

标签: javascript jquery html mutation-observers

是否有可能以及如何从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>

0 个答案:

没有答案