简体   繁体   中英

Running javascript in the Google Chrome extension after a page has done loading

The website I'm targeting is pretty much a Javascript application. So I need to add HTML after everything has completed loading. I tried using MutationObserver, but it still tries to execute javascript too early and I get the following error code `Uncaught TypeError: Cannot read property 'appendChild' of undefined

My code

manifest.json

{
  "manifest_version": 2,

  "name": "Test",
  "version": "1.0",
  "description": "Test Description",

  "content_scripts": [{
    "js": ["content.js"],
    "run_at" : "document_idle",
    "matches": ["https://pastvu.com/p/*"]
  }]

}

content.js

new MutationObserver(function(mutations, observer) {
    addHtml();
    observer.disconnect();
}).observe(document.querySelector('body'), {childList: true});


function addHtml(){

    var newDiv = document.createElement("div");
    newDiv.setAttribute("class","tltp-wrap");

    var newLink = document.createElement('a');
    newLink.setAttribute('href','http://www.google.com');

    var linkButton = document.createElement('span');
    linkButton.setAttribute('class','glyphicon glyphicon-map-marker');

    newLink.appendChild(linkButton);
    newDiv.appendChild(newLink);

    document.getElementsByClassName("toolsBtm")[0].appendChild(newDiv);
}

Here is the page I'm targeting. As you can see the <body> looks like this

<body>
    <script type="text/javascript" src="/js/module/appMain.js?__=wfDkO"></script>
</body>

My goal is to wait until the body html loads or at least unitil .toolsBtm div is present.

I changed content.js to this and still no luck

new MutationObserver(function(mutations, observer) {
    var bodyLoaded = document.getElementsByClassName('toolsBtm');
    if (bodyLoaded.length > 0) {
        alert('a');
        addHtml();
    }
}).observe(document.querySelector('body'), {childList: true});


function addHtml(){

    var newDiv = document.createElement("div");
    newDiv.setAttribute("class","tltp-wrap");

    var newLink = document.createElement('a');
    newLink.setAttribute('href','http://www.google.com');

    var linkButton = document.createElement('span');
    linkButton.setAttribute('class','glyphicon glyphicon-map-marker');

    newLink.appendChild(linkButton);
    newDiv.appendChild(newLink);

    document.getElementsByClassName("toolsBtm")[0].appendChild(newDiv);
}

In our plugin we have something like

export function invokeAfterDomIsReady(context = document, selector, time = 400, func) {
    const domEl = context.querySelector(selector);
    if (domEl != null) {
        func(domEl);
    } else {
        setTimeout(function () {
            invokeAfterDomIsReady(context, selector, time, func);
        }, time);
    }
}

It is something what usually used during ui testing with Selenium.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM