1

I'm writing a Chrome extension that injects a javascript file into a page to add a button. When I go to the website I want to modify, the button always takes a fraction of a second longer to load after the page loads. Is there a way that I can load the button at the same time as the other elements on the page? I have tried using MutationObserver, but I can't seem to figure it out.

manifest.json file:

{
    "name": "Some extension",
    "version": "1.0",
    "description": "Some description",

    "content_scripts": [
        {
            "js": ["script.js"],
            "run_at": "document_start",
            "matches": ["https://*.familysearch.org/*"]
        }
    ],
    "manifest_version": 2
}

Script to be injected:

// Create a button and append it to an element with a class of 'primaryNav'
let navElement = document.getElementById('primaryNav');
let newElement = document.createElement('button');
newElement.classList.add('primary-nav-text');
newElement.classList.add('nav-menu-trigger');
let textNode = document.createTextNode("FHTL");
newElement.append(textNode);
navElement.append(newElement);

I've tried this just to see if I can get MutationObserver to work:

const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.addedNodes.length) {
            console.log(mutation.addedNodes[0]);
        }
    });
});
const navBar = document.getElementById('primaryNav');
observer.observe(navBar, {
    childList: true
});

But I get this error (I assume it's because that element has not loaded yet):

Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.

Heading

janksmap
  • 61
  • 1
  • 2
  • 7

1 Answers1

0

As said in the documentation regarding "run_at": "document_start", the DOM isn't loaded when your script runs so it can't find the nav element.

Replace it with "run_at": "document_end", and the script will be executed right after the DOM loads.

And regarding your MutationObserver error, as it states, navBar isn't a Node because .getElementById doesn't return a node.

Luka Čelebić
  • 1,083
  • 11
  • 21
  • The author can't use document_end because the goal is to augment the element instantly once it appears in DOM. By the time document_end occurs, the browser may have already shown the page with the original nonmodified content, which is what the author wants to avoid. – wOxxOm Dec 23 '20 at 09:20