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 listene
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.
{
"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
}
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) {
const toRemove = [];
for (const {addedNodes} of mutations) {
for (const n of addedNodes) {
if (n.tagName) {
if (n.matches(DEL_SELECTOR)) {
toRemove.push(n);
} else if (n.firstElementChild && n.querySelector(DEL_SELECTOR)) {
toRemove.push(...n.querySelectorAll(DEL_SELECTOR));
}
}
}
}
if (toRemove.length) {
mo.disconnect();
for (const el of toRemove) el.remove();
observe();
}
}
function observe() {
mo.observe(document, {
subtree: true,
childList: true,
});
}
Notes:
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.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
.