获取添加的DOM节点的className(mutationObserver)

Cli*_*iff 3 javascript dom mutation-observers

我正在编写一个简单的用户脚本,如果它包含某个单词列表,它将自动隐藏Facebook帖子.核心功能的作品,但我MutationObserver似乎没有阅读classNamemutation.addedNodes正确.我遍历mutation.addedNodes并检查这些元素中是否有任何类具有该类userContentWrapper,但该测试的结果始终为false - 即使该元素确实具有该类.

var startObserver = function() {        
    var observer = new MutationObserver(function(mutations) {        
        mutations.forEach(function(mutation) {            
            var added = mutation.addedNodes;            
            for (var i = 0; i < added.length; i++) {                
                if (/\buserContentWrapper\b/.test(added[i].className)) {
                    processFilter(added[i]);
                }
            }
        });        
    });    
    var obj = {childList: true, subtree: true, attributes: true};
    observer.observe(document.documentElement, obj);
};
Run Code Online (Sandbox Code Playgroud)

我只能假设观察者在完全形成所有属性之前分析添加的节点.如何使观察者等待处理节点直到它完全完成?或者我不明白这个问题?

提前致谢...

wOx*_*xOm 6

一些添加的节点是容器,因此您应该深入挖掘:

var startObserver = function() {
    var observer = new MutationObserver(function(mutations) {
        for (var m=0; m < mutations.length; m++) {
            var added = mutations[m].addedNodes;
            for (var i = 0; i < added.length; i++) {
                var node = added[i];
                if (node.nodeType != 1) { // not Node.ELEMENT_NODE
                    continue;
                }
                if (/\buserContentWrapper\b/.test(node.className)) {
                    processFilter(node);
                } else if (node.children.length) {
                    var nodes = node.getElementsByTagName('userContentWrapper');
                    for (var j = 0; j < nodes.length; j++) {
                        processFilter(nodes[j]);
                    }
                }
            }
        }
    });
    observer.observe(document, {childList: true, subtree: true});
};
Run Code Online (Sandbox Code Playgroud)

MutationObserver回调作为一个阻止DOM和JS引擎的微任务执行,所以它应该非常快,特别是在像facebook这样的复杂网站上,它会产生大量的DOM突变.

这可以在devtools(F12关键)分析器/时间线面板中进行测试.

如果要最小化使用MutationObserver的不利影响,请将大批更改推迟到下一个事件任务中:

var startObserver = function() {
    new MutationObserver(function handler(mutations, observer, postponed) {
        if (mutations.length > 100 && postponed !== true) {
            setTimeout(handler, 0, mutations, observer, true);
            return;
        }
        for (var m=0; m < mutations.length; m++) {
            var added = mutations[m].addedNodes;
            for (var i = 0; i < added.length; i++) {
                var node = added[i];
                if (node.nodeType != 1) { // not Node.ELEMENT_NODE
                    continue;
                }
                if (node.classList.contains('userContentWrapper')) {
                    processFilter(node);
                } else if (node.children[0]) {
                    var nodes = node.getElementsByClassName('userContentWrapper');
                    for (var j = 0; j < nodes.length; j++) {
                        processFilter(nodes[j]);
                    }
                }
            }
        }
    }).observe(document, {childList: true, subtree: true});
};
Run Code Online (Sandbox Code Playgroud)