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 therun_at
property. Fortabs.executeScript()
, it is therunAt
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
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 after
DOMContentLoaded
has fired, but before thewindow
load
event fires.document_idle
The injection takes place sometime after
document_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:window
load
event fires, orDOMContentLoaded
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.When listening for
DOMContentLoaded
, orwindow
load
, you should checkdocument.readyState
firstAny time you use a
DOMContentLoaded
listener, or awindow
load
listener, you should always check thedocument.readyState
prior to adding the listener to make sure that you are adding the listener prior to theDOMContentLoaded
event being fired (or prior to theload
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:For adding a
window
load
listener, you could use something like: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.