Javascript not always working in Chrome Extension, when should I run it?

不羁岁月 提交于 2019-12-03 16:48:30

If the code is not always working, then that suggests that the element(s) are being created/loaded by the page's javascript. So, you need to use standard AJAX-aware techniques to move that div.

The techniques are: timers, mutation observers, mutation events, and intercepting AJAX XHR (if applicable). These are all discussed in other Stack Overflow questions, but: mutation events are deprecated/buggy; intercepting XHR gets messy and may not apply here; and mutation observers can get complicated.

I'd recommend downloading and adding the waitForKeyElements() utility to your manifest.

Then the code to move that <div> becomes merely:

waitForKeyElements (
    "jQuery selector for div(s) you want to move",
    moveSelectDivs
);
function moveSelectDivs (jNode) {
    jNode.insertBefore ("APPROPRIATE JQUERY SELECTOR");
}


Keep your manifest set to run at document_end. This is equivalent to DOMContentLoaded -- which is when $(document).ready() fires. The default run_at fires too late and at unpredictable times. run_at document_start won't do any good, since: timers, mutation observers, etc. all will not fire until after the DOMContentLoaded event -- for current versions of Chrome anyway (Other browsers don't have the same limits).



Alternate method, for the fastest action but slower webpage:

Regarding:

(the page is loading and then you can see the div move), which is something I wish to avoid.

There are only two ways to do anything before DOMContentLoaded that work in Chrome:

  1. You can set mycss.css to hide the div until after you've moved it. This might be the most cost-effective method, performance wise.
  2. Or, you can override document.createElement(). This will respond to the new element as fast as possible (assuming it's created before DOMContentLoaded), but it might slow down the page overall, by a noticeable amount.

Set the content script to run at document_start, and the override code must be injected. So, the script would look like:

addJS_Node (null, null, scriptMain);

function scriptMain () {
    var _orig_createElement = document.createElement;

    document.createElement  = function (tag) {
        var element = _orig_createElement.call (document, tag);

        var movingNode      = document.querySelector ("MOVING DIV SELECTOR");
        if (movingNode) {
            var target      = document.querySelector ("TARGET DIV SELECTOR");
            if (target) {
                target.parentNode.insertBefore (movingNode, target);

                document.createElement = _orig_createElement;
            }
        }

        return element;
    };
}

function addJS_Node (text, s_URL, funcToRun) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}


Do not try to use jQuery for this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!