在页面显示到屏幕之前删除DOM元素(在Chrome扩展程序中)

irr*_*lar 7 javascript google-chrome-extension

我试图创建一个扩展,在页面显示到屏幕之前将删除某些页面元素(通过id或类).我已尝试在文档中使用"DOMContentLoaded"作为事件的事件监听器,但javascript似乎在页面显示给用户后执行,然后将其删除,因此它不如我想要的那么顺畅(不显示不需要的内容)在所有)

document.addEventListener("DOMContentLoaded", function() {

var elements = document.getElementsByClassName("header-nav-item");
while(elements.length > 0){
    elements[0].parentNode.removeChild(elements[0]);
}

var element = document.getElementById("topchapter");
element.parentNode.removeChild(element);
element = document.getElementById("wrapper_header");
    element.parentNode.removeChild(element);

});
Run Code Online (Sandbox Code Playgroud)

这是我的扩展程序使用的内容脚本,在加载页面后删除.在用户看到页面之前,我需要使用什么来修改DOM?

wOx*_*xOm 12

在注入的内容脚本中使用MutationObserverdocument-start实际上在页面加载期间从DOM中删除HTML元素,然后再渲染它们,这样就不会出现闪烁.

  • manifest.json的:

    {
        "name": "Delete elements",
        "version": "1.0",
        "content_scripts": [
            {
                "matches": ["http://somesite.com/*"],
                "run_at": "document_start",
                "all_frames": true,
                "js": ["content.js"]
            }
        ],
        "manifest_version": 2
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • content.js:

    deleteElements('.header-nav-item, #topchapter, #wrapper_header');
    
    function deleteElements(selector) {
        // in case the content script was injected after the page is partially loaded
        doDelete(document.querySelectorAll(selector));
    
        var mo = new MutationObserver(process);
        mo.observe(document, {subtree:true, childList:true});
        document.addEventListener('DOMContentLoaded', function() { mo.disconnect() });
    
        function process(mutations) {
            for (var i = 0; i < mutations.length; i++) {
                var nodes = mutations[i].addedNodes;
                for (var j = 0; j < nodes.length; j++) {
                    var n = nodes[j];
                    if (n.nodeType != 1) // only process Node.ELEMENT_NODE
                        continue;
                    doDelete(n.matches(selector) ? [n] : n.querySelectorAll(selector));
                }
            }
        }
        function doDelete(nodes) {
            [].forEach.call(nodes, function(node) { node.remove() });
        }
    }
    
    // Chrome pre-34
    if (!Element.prototype.matches)
        Element.prototype.matches = Element.prototype.webkitMatchesSelector;
    
    Run Code Online (Sandbox Code Playgroud)

笔记:

  • 观察者回调必须简单快速,以便在页面加载期间不引入滞后,因此普通for循环优于forEach回调.
  • 完成工作后,最好立即断开观察者的连接,以免不必要地观察页面的其余部分.
  • 不要添加多个观察者,只将一个检查合并到一个中
  • mutationsarray还包含文本子节点以及添加的元素本身.这就是为什么我们检查,如果nodeTypeNode.ELEMENT_NODE相当于1.
  • 每个变异的addedNodes数组通常都有容器元素DIV,例如,它们可能有一个我们想要删除的元素.所以我们必须用querySelector或检查它querySelectorAll.
  • childNode.remove()从Chrome 23开始运行