我正在尝试对扩展程序进行编码,以纠正1个论坛上的拼写错误。

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

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

当添加为扩展名时,它并没有改变任何东西,显然,如果我对页面进行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"]
}

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

最佳答案

您正在监听火灾的事件之后注入(inject)脚本(在本例中为 DOMContentLoaded )。因此,将不会执行您在侦听器中拥有的任何代码,因为在添加侦听器之后该事件永远不会触发。

在Chrome扩展程序和Firefox WebExtensions中,当指定注入(inject)content script的时间时,可以指定"document_start""document_end""document_idle" .1在manifest.json中,这是run_at属性的值。对于 tabs.executeScript() ,它是runAt属性。

  • document_start注入(inject)发生在创建DOM或运行页面中的脚本之前。这意味着document.bodydocument.head尚不存在。尚未触发DOMContentLoadedwindow load事件。您可以通过将它们添加到document.documentElement来将它们添加到DOM。您可能需要使用 MutationObserver 来监视有兴趣添加到DOM中的元素,或者等待DOMContentLoaded之类的事件来指示DOM可用。
  • document_end(默认)
    注入(inject)在DOM完成之后但在子资源(例如图像和帧)加载之前进行。通常是在触发DOMContentLoaded之后,但在window load事件触发之前。
  • document_idle注入(inject)发生在document_end之后的某个时间,并且在window load事件触发后立即进行。 answer to "When does a run_at: document_idle content script run?"表示这是以下两者中的较早版本:
  • 触发window load事件后,或
  • DOMContentLoaded事件触发后200ms。
    这意味着您的内容脚本将在DOMContentLoaded触发后注入(inject),但是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.
    }
    

    要添加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.
    }
    

  • 如果您使用的是tabs.executeScript(),则为runAt提供的值仅表示您希望最早注入(inject)脚本。如果您在该时间之前执行tabs.executeScript(),则注入(inject)将延迟到指定时间。请注意,对于document_start,执行tabs.executeScript()时的点将对新页面有效,这是一个复杂的主题,值得提出自己的问题/答案。
  • 此答案的一部分是从my answer to "Detect and handle a button click in the active HTML page"复制而来的。
  • 关于javascript - Chrome内容脚本无法正常工作:DOMContentLoaded监听器无法执行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43233115/

    10-11 06:11