Chrome内容脚本无效:DOMContentLoaded侦听器无法执行

J m*_*ris 10 javascript google-chrome google-chrome-extension content-script

我正在尝试编码扩展,以纠正1个论坛上的拼写错误.

我正在尝试<p>使用内容脚本访问标记,但它不会更改任何内容(使用下面的代码):

document.addEventListener("DOMContentLoaded", function() {
    document.getElementsByTagName("P")[4].innerHTML = "correct_word"; 
}); 
Run Code Online (Sandbox Code Playgroud)

当作为扩展添加时它不会改变任何东西,显然如果我wget是页面,并将脚本放在那里,一切正常.有什么想法吗?

我的manifest.json文件:

{
    "manifest_version": 2,
    "name": "Extension",
    "description": "Description",
    "version": "1.0",
    "content_scripts": [{
        "run_at": "document_end",
        "matches": ["http://example.com/"],
        "js": ["script.js"]
    }],
    "web_accessible_resources": ["Filedeleted(really).html"]
}
Run Code Online (Sandbox Code Playgroud)

我知道内容脚本和WWW页面有不同的沙箱,也许内容脚本无法访问页面(和标签)?

Mak*_*yen 16

您正在侦听火灾事件后注入脚本(在本例中DOMContentLoaded).因此,您在侦听器中的任何代码都不会被执行,因为在添加侦听器后事件永远不会触发.

在Chrome扩展和Firefox WebExtensions,指定时间时一个内容脚本被注入,您可以指定"document_start","document_end""document_idle".1manifest.json中,这是为该run_at属性声明的值.因为tabs.executeScript(),这是runAt财产.

  • document_start
    注入发生在创建DOM之前,或者来自正在运行的页面的脚本.这意味着,document.bodydocument.head尚不存在.在DOMContentLoadedwindow load事件还没有被解雇.您可以通过将它们添加到DOM来向DOM添加内容document.documentElement.您可能需要使用a MutationObserver来监视您有兴趣添加到DOM的元素,或者等待DOMContentLoaded表明DOM可用的事件.
  • document_end(默认)
    注入在DOM完成之后但在加载子资源(例如图像和帧)之前进行.这通常是在DOMContentLoaded被解雇之后,但在window load事件发生之前.
  • document_idle
    注射发生document_endwindow load事件发生之后和之后的某个时间.在回答"什么时候一个run_at:document_idle内容脚本运行?" 表示这是较早的:

    • 在后window load事件触发,或
    • DOMContentLoaded事件发生后200ms .

    这意味着您的内容脚本将在DOMContentLoaded触发后注入,但该window load事件可能已经或可能没有被触发.

当监听DOMContentLoaded,或者window load,你应该检查document.readyState第一

无论何时使用DOMContentLoaded监听器或window load监听器,都应该document.readyState在添加监听器之前检查以确保在DOMContentLoaded事件被触发之前添加监听器(或者在事件被触发之前添加监听器load,如果这是你的话正在倾听).当你想听这些事件时,这应该是正常的习惯.如果在事件触发后添加侦听器,则永远不会运行侦听器.

要添加DOMContentLoaded侦听器,您应该使用以下内容:

if(document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded',afterDOMLoaded);
} else {
    afterDOMLoaded();
}

function afterDOMLoaded(){
    //Everything that needs to happen after the DOM has initially loaded.
}
Run Code Online (Sandbox Code Playgroud)

要添加window load侦听器,您可以使用以下内容:

if(document.readyState !== 'complete') {
    window.addEventListener('load',afterWindowLoaded);
} else {
    afterWindowLoaded();
}

function afterWindowLoaded(){
    //Everything that needs to happen after the window is fully loaded.
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果您正在使用tabs.executeScript(),则您提供的值runAt仅表示您希望脚本注入最早的值.如果您在此tabs.executeScript()之前执行,则注射会延迟到指定的时间.请注意,对于document_start执行该点tabs.executeScript()对新页面有效的点是一个复杂的主题,值得自己提问/回答.
  2. 我的回答"检测并处理活动HTML页面中的按钮单击"复制了此答案的部分内容.

  • oooooo myy godd 4 小时后...非常感谢你。StackOverflow 上的其他答案都没有解释 document.readyState (2认同)