在页面显示到屏幕之前删除 DOM 元素(在 Chrome 扩展中) [英] Deleting DOM elements before the Page is displayed to the screen (in a Chrome extension)

查看:23
本文介绍了在页面显示到屏幕之前删除 DOM 元素(在 Chrome 扩展中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个扩展程序,该扩展程序将在页面显示到屏幕上之前删除某些页面元素(通过 id 或类).我尝试在文档上使用事件侦听器,并将DOMContentLoaded"作为事件,但 javascript 似乎在页面显示给用户后执行,然后将其删除,因此它不像我想要的那样流畅(不显示不需要的内容)一点)

I am trying to create an extension that will get rid of certain Page elements (by id or class) before the page is displayed to the screen. I've tried using an event listener on the document with "DOMContentLoaded" as the event but the javascript seems to execute after the page is displayed to the user and then deletes it so it's not as smooth as I want (not showing the unwanted content at all)

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);

});

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

This is the content script that my extension uses which deletes after the page is loaded. What do I need to use to modify the DOM before the pages is seen by the user?

推荐答案

使用 MutationObserver 用于在页面加载期间实际从 DOM 中删除 HTML 元素,然后再呈现它们,以免出现闪烁.

Use MutationObserver in the content script injected at document_start to actually delete the HTML elements from DOM during page load before they are rendered so that there's no flickering.

  • manifest.json:
{
  "name": "Delete elements",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": ["*://somesite.com/*"],
      "run_at": "document_start",
      "all_frames": true,
      "js": ["content.js"]
    }
  ],
  "manifest_version": 2
}

  • content.js:
  • const DEL_SELECTOR = '.header-nav-item, #topchapter, #wrapper_header';
    
    const mo = new MutationObserver(onMutation);
    // in case the content script was injected after the page is partially loaded
    onMutation([{addedNodes: [document.documentElement]}]);
    observe();
    
    function onMutation(mutations) {
      let stopped;
      for (const {addedNodes} of mutations) {
        for (const n of addedNodes) {
          if (n.tagName) {
            if (n.matches(DEL_SELECTOR)) {
              stopped = true;
              mo.disconnect();
              n.remove();
            } else if (n.firstElementChild && n.querySelector(DEL_SELECTOR)) {
              stopped = true;
              mo.disconnect();
              for (const el of querySelectorAll(DEL_SELECTOR)) el.remove();
            }
          }
        }
      }
      if (stopped) observe();
    }
    
    function observe() {
      mo.observe(document, {
        subtree: true,
        childList: true,
      });
    }
    

    注意事项:

    • 观察者回调必须简单快速,以免在页面加载过程中引入延迟,因此请使用简单的选择器和直接 DOM 访问,而不是 jQuery.
    • 工作完成后,最好立即断开观察者的连接,以免不必要地观察页面的其余部分.
    • 不要添加多个观察者,将所有检查合并到一个中
    • mutations 数组还包含 文本子节点 以及添加的元素本身.这就是为什么我们要确保 tagName 存在 - 这意味着节点是一个元素.
    • 每个mutation的 addedNodes数组通常都有容器元素,例如DIV,其中又可能有我们想要删除的元素.所以我们必须用 querySelectorquerySelectorAll 来检查它.
    • childNode.remove() 有效铬 23
    • The observer callback must be simple and fast in order not to introduce lags during page loading so use simple selectors and direct DOM access instead of jQuery.
    • When the job is done it's best to disconnect the observer immediately so that the rest of the page isn't needlessly observed.
    • Don't add multiple observers, incorporate all checks in just one
    • mutations array also contains text subnodes along with the added elements themselves. That's why we make sure tagName is present - it means the node is an element.
    • Each mutation's addedNodes array usually has container elements like DIV, for example, which in turn may have an element we want to delete inside. So we have to examine it with querySelector or querySelectorAll.
    • childNode.remove() works since Chrome 23

    这篇关于在页面显示到屏幕之前删除 DOM 元素(在 Chrome 扩展中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆