I have a Chrome extension, and I want to wait until an element is loaded before injecting content into the page.
I'm trying to inject a button:
myButton = document.createElement('button');
myButton.class = 'mybutton';
document.querySelector('.element_id').appendChild(myButton)
I have this at the top of my content script. It used to work just fine, but then it stopped working. The error that was displayed was:
Uncaught TypeError: Cannot read property 'appendChild' of null
In order to wait for the element with class id .element_id to load, I tried to use a MutationObserver
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (!mutation.addedNodes) return
        for (var i = 0; i < mutation.addedNodes.length; i++) {
            if (mutation.addedNodes[i].parentNode == document.querySelector('#outer-container')) {
                myButton = document.createElement('button');
                myButton.class = 'mybutton';
                document.querySelector('.element_id').appendChild(myButton)
        }
            var node = mutation.addedNodes[i]
        }
    })
})
observer.observe(document.body, {
    childList: true
    , subtree: true
    , attributes: false
    , characterData: false
})
When I used the mutation observer, the page would load an outer div element called outer-container, and there was no way for me to directly compare the class .element_id. The class .element_id is nested a number of layers into the outer div.
HOWEVER, the above did not work, and I still received the null property error.
Is there a better way to wait for some element to be loaded (which is loaded async), before injecting?
Don't forget to add childList and subtree property when observing changes.
var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        if (!mutation.addedNodes) {
            return;
        }
        for (var i = 0; i < mutation.addedNodes.length; i++) {
            if (mutation.addedNodes[i].classList.contains("element_id")) {
                // Your logic here
            }
        }
    });
});
observer.observe(document.body, {
    childList: true,
    subtree: true
});
                        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