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);
});
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?
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": ["*://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) {
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 n.querySelectorAll(DEL_SELECTOR)) el.remove();
}
}
}
}
if (stopped) 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
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With