Chrome内容脚本无效:DOMContentLoaded监听器不执行 [英] Chrome content scripts aren't working: DOMContentLoaded listener does not execute
问题描述
我试图访问< 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_start
,document_end
或document_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>
- 如果您使用
tabs.executeScript()
,您为runAt
提供的值仅指示您最早的希望脚本被注入。如果您在该时间之前正在执行tabs.executeScript()
,则注入延迟至指定的时间。请注意,对于document_start
执行tabs.executeScript()
时的要点对新页面有效是一个复杂的主题,这是值得自己的问题/答案。
- 这个答案的一部分是从我的回答检测并处理活动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 thatdocument.body
anddocument.head
do not yet exist. TheDOMContentLoaded
andwindow
load
events have not yet fired. You can add things to the DOM by adding them to thedocument.documentElement
. You may need to use aMutationObserver
to watch for the elements you are interested in being added to the DOM, or wait for an event likeDOMContentLoaded
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 afterDOMContentLoaded
has fired, but before thewindow
load
event fires.document_idle
The injection takes place sometime afterdocument_end
and immediately after thewindow
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 thewindow
load
event may, or may not, have already fired.- After the
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.
}
- If you are using
tabs.executeScript()
, the value that you provide forrunAt
only indicates the earliest you want the script to be injected. If you are executingtabs.executeScript()
prior to that time, then the injection is delayed until the specified time. Note that fordocument_start
the point when executingtabs.executeScript()
will be valid for a new page is a complex topic, which deserves its own question/answer. - Portions of this answer were copied from my answer to "Detect and handle a button click in the active HTML page".
这篇关于Chrome内容脚本无效:DOMContentLoaded监听器不执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!