如何在页面的 Javascript 执行后加载内容脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13917047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 15:07:39  来源:igfitidea点击:

How to get a content script to load AFTER a page's Javascript has executed?

javascriptgoogle-chrome-extensioncontent-script

提问by FractalBob

My extension is supposed to load a content script, searchTopic.js, only after the page it's injected into has already fully loaded (yes, I have set "run_at" to "document_end" in the extension manifest), but in fact it's loading before all the DOM objects have been created (the crucial ones are created via some Javascript in the page). So, the question is, how can I wait until the page's Javascript has executed? Here's my manifest:

我的扩展应该加载一个内容脚本,searchTopic.js,只有在它注入的页面已经完全加载之后(是的,我在扩展清单中将“run_at”设置为“document_end”),但实际上它是在加载之前所有 DOM 对象都已创建(关键的对象是通过页面中的一些 Javascript 创建的)。所以,问题是,我怎样才能等到页面的 Javascript 执行完毕?这是我的清单:

"content_scripts": [
  {
  "run_at": "document_end",
  "matches": ["https://groups.google.com/forum/*"],
  "js": ["searchTopic.js"]
  }
],

回答by Brock Adams

"run_at": "document_end"is the equivalent to DOMContentLoaded.That is, it fires after the staticHTML is loaded, but before slow images and slow finishing javascript.

"run_at": "document_end"相当于DOMContentLoaded也就是说,它在加载静态HTML之后触发,但在慢速图像和慢速完成 javascript 之前触发。

So you cannot set a content script to fire after the page's JS, just by setting the manifest alone. You must code for this in the content script itself.

因此,您不能仅通过单独设置清单来设置内容脚本以在页面的 JS 之后触发。您必须在内容脚本本身中为此编码。

For content scripts, "run_at": "document_end"will fire before the onloadevent (unlike the default document_idle-- which can fire at unpredictable times).

对于内容脚本,"run_at": "document_end"将在onload事件之前触发(与默认值不同document_idle——它可以在不可预测的时间触发)。

So, the first step is to wait for the loadevent with code like this in your content script (searchTopic.js):

因此,第一步是load在您的内容脚本 ( searchTopic.js) 中使用如下代码等待事件:

window.addEventListener ("load", myMain, false);

function myMain (evt) {
    // DO YOUR STUFF HERE.
}


In the case where the script you care about takes a while to finish, you will have to poll for some condition on a case-by-case basis. For example:


如果您关心的脚本需要一段时间才能完成,您将不得不根据具体情况轮询某些条件。例如:

window.addEventListener ("load", myMain, false);

function myMain (evt) {
    var jsInitChecktimer = setInterval (checkForJS_Finish, 111);

    function checkForJS_Finish () {
        if (    typeof SOME_GLOBAL_VAR != "undefined"
            ||  document.querySelector ("SOME_INDICATOR_NODE_css_SELECTOR")
        ) {
            clearInterval (jsInitChecktimer);
            // DO YOUR STUFF HERE.
        }
    }
}

回答by Aaron Digulla

scriptelements are executed in order. The browser even stops loading DOM content if there are scriptnodes in the body. This is guaranteed to work, otherwise document.write()would stop working.

script元素按顺序执行。如果在浏览器甚至停止加载内容DOMscript中的节点body。这是保证工作,否则document.write()将停止工作。

So you have two solutions:

所以你有两个解决方案:

  1. Use the onloadevent to load your code.
  2. Add a script tag as the last element of the page (last thing in the bodyelement). This script will be executed after all other scripts have finished andafter the body has been converted to a DOM tree.
  1. 使用该onload事件加载您的代码。
  2. 添加脚本标记作为页面的最后一个元素(元素中的最后一个body元素)。此脚本将在所有其他脚本完成主体转换为 DOM 树后执行。

回答by STEEL

You use window.load method.

您使用 window.load 方法。

function addLoadEvent(a) {
    var b = window.onload;
    "function" != typeof window.onload ? window.onload = a : window.onload = function () {
        b && b(),
            a()
    }
}
function init() {
    alert('init');
}
addLoadEvent(init);