Chrome extension set to `run_at` `document_start` is running too fast?
Chrome extension Content scripts (run from a manifest.json
) that are run at document_start
, do fire before document.readyState
Doc has reached interactive
-- which is the earliest you want to start messing with most page elements.
However, you can inject most <script>
nodes right away if you wish. Just not to document.head
or document.body
because they don't exist yet.
Append to documentElement
instead. For example:
var s = document.createElement ("script");
s.src = "http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js";
s.async = false;
document.documentElement.appendChild (s);
Or
var s = document.createElement ("script");
s.src = chrome.extension.getURL ("MyPwnCode.js");
s.async = false;
document.documentElement.appendChild (s);
If you are adding or modifying other DOM elements, in a script running at document_start
, wait until the DOMContentLoaded
event like so:
document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
function fireContentLoadedEvent () {
console.log ("DOMContentLoaded");
// PUT YOUR CODE HERE.
//document.body.textContent = "Changed this!";
}
Your problem is that, when using "run_at": "document_start"
, the only element that is granted to exist in the DOM is the <html>
element. If you want to avoid errors relative to page load, like trying to access some element that hasn't been created yet, you'll have to either:
Make your script run at
"document_idle"
or"document_end"
. Although"document_end"
still doesn't grant you that all the elements and resources of the page have been fully loaded (but the DOM has already been parsed), the"document_idle"
keyword will give you the certainty that the DOM has been parsed and all the elements and resources have been loaded properly before your script runs.Or, instead, you can continue using
"document_start"
wrapping your code inside a"DOMContentLoaded"
listener, which will make it run when the DOM has completely finished loading and parsing, similarly to"document_idle"
. Here's an example:document.addEventListener("DOMContentLoaded", function() { // Run your code here... });