Chrome内容脚本无效:DOMContentLoaded监听器不执行 [英] Chrome content scripts aren't working: DOMContentLoaded listener does not execute

查看:1359
本文介绍了Chrome内容脚本无效:DOMContentLoaded监听器不执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我试图访问< 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页面有不同的沙箱,也许内容脚本无法访问页面(和标签)?

解决方案

在您正在侦听的事件之后,您正在注入脚本(在这种情况下, DOMContentLoaded )。因此,您在侦听器中拥有的任何代码都不会执行,因为事件在您添加侦听器后永远不会触发。



在Chrome扩展和Firefox WebExtensions中,指定注入内容脚本的时间,您可以指定 document_startdocument_enddocument_idle 1 manifest.json 中,这是为 run_at 属性指定的值。对于 tabs.executeScript() ,它是 runAt 属性。




  • document_start

    注入发生在DOM创建之前,或者正在运行页面的脚本。这意味着 document.body document.head 还不存在。 > DOMContentLoaded 窗口 加载事件尚未开始。您可以通过将它们添加到 document.documentElement 来将其添加到DOM中。您可能需要使用 MutationObserver 来监视您有兴趣添加到DOM中的元素,或者等待像 DOMContentLoaded 这样的事件指示DOM可用。

  • document_end (默认)

    注入发生在DOM完成后,但在子资源(例如图像和帧)被加载。这通常在> DOMContentLoaded 已经被触发,但在窗口之前 load
  • document_idle

    注入发生在<$ c $之后c> document_end
    并紧接在窗口之后 load 事件触发。 回答run_at:document_idle内容脚本何时运行?表示这是以前的




    • 窗口 加载事件之后在$ DOMContentLoaded 事件触发后200毫秒,



    这意味着您的内容脚本将在 DOMContentLoaded 被触发后注入,但窗口 加载事件可能会或可能不会被触发。




< h2>收听 DOMContentLoaded 时,或 window load ,您应该检查 document.readyState 第一个

任何时候您使用 DOMContentLoaded 监听r或窗口 load 侦听器,您应该始终检查 document.readyState ,然后将侦听器添加到确保在被激发的 DOMContentLoaded 事件之前添加侦听器(或者在 load >事件被触发之前添加侦听器,如果这是你正在听的)。当你想听这些事件时,这应该是正常的习惯。如果在事件触发后添加侦听器,侦听器将永远不会运行。



添加 DOMContentLoaded 听众,你应该使用类似于:


$ b

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

函数afterDOMLoaded(){
// DOM最初加载后需要发生的所有事情。



添加窗口 load listener,你可以使用类似于:



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

函数afterWindowLoaded(){
//窗口完全加载后需要发生的一切。

$ / code>







  1. 如果您使用 tabs.executeScript(),您为 runAt 提供的值仅指示您最早的希望脚本被注入。如果您在该时间之前正在执行 tabs.executeScript(),则注入延迟至指定的时间。请注意,对于 document_start 执行 tabs.executeScript()时的要点对新页面有效是一个复杂的主题,这是值得自己的问题/答案。
  2. 这个答案的一部分是从我的回答检测并处理活动HTML页面中的按钮点击


I am trying to code extension that corrects misspellings on 1 forum.

I am trying to access <p> tag, with content script, but it doesn't change anything (using the code below):

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

It doesn't change anything when added as an extension, apparently if I wget the page, and put the script there, all works. Any thoughts?

My manifest.json file:

{
    "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"]
}

I know content scripts and WWW pages have different sandboxes, maybe content script can't access page (and tag)?

解决方案

You are injecting your script after the event you are listening for fires (in this case, DOMContentLoaded). Thus, any code that you have in the listener will not be executed, because the event never fires after you have added your listener.

In Chrome extensions and Firefox WebExtensions, when specifying a time for a content script to be injected, you can specify "document_start", "document_end", or "document_idle".1 In a manifest.json this is the value stated for the run_at property. For tabs.executeScript(), it is the runAt property.

  • document_start
    The injection takes place prior to the DOM being created, or scripts from the page being run. This means that document.body and document.head do not yet exist. The DOMContentLoaded and window load events have not yet fired. You can add things to the DOM by adding them to the document.documentElement. You may need to use a MutationObserver to watch for the elements you are interested in being added to the DOM, or wait for an event like DOMContentLoaded to indicate that the DOM is available.
  • document_end (default)
    The injection takes place after the DOM is complete, but before subresources (e.g. images and frames) are loaded. This is usually after DOMContentLoaded has fired, but before the window load event fires.
  • document_idle
    The injection takes place sometime after document_end and immediately after the window load event fires. The answer to "When does a run_at: document_idle content script run?" indicates that this is the earlier of:

    • After the window load event fires, or
    • 200ms after the DOMContentLoaded event fired.

    This means that your content script will be injected after DOMContentLoaded has fired, but the window load event may, or may not, have already fired.

When listening for DOMContentLoaded, or window load, you should check document.readyState first

Any time you use a DOMContentLoaded listener, or a window load listener, you should always check the document.readyState prior to adding the listener to make sure that you are adding the listener prior to the DOMContentLoaded event being fired (or prior to the load event being fired, if that is what you are listening for). This should be normal habit when you want to listen for these events. If you add the listener after the event has fired, the listener will never be run.

For adding a DOMContentLoaded listener, you should use something like:

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

function afterDOMLoaded(){
    //Everything that needs to happen after the DOM has initially loaded.
}

For adding a window load listener, you could use something like:

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

function afterWindowLoaded(){
    //Everything that needs to happen after the window is fully loaded.
}


  1. If you are using tabs.executeScript(), the value that you provide for runAt only indicates the earliest you want the script to be injected. If you are executing tabs.executeScript() prior to that time, then the injection is delayed until the specified time. Note that for document_start the point when executing tabs.executeScript() will be valid for a new page is a complex topic, which deserves its own question/answer.
  2. Portions of this answer were copied from my answer to "Detect and handle a button click in the active HTML page".

这篇关于Chrome内容脚本无效:DOMContentLoaded监听器不执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆