Chrome's Content scripts are executed in a Sandboxed environment [source]. There is no direct way to communicate with the global (window
) object.
Another common pitfall is that the developer forgets how/when the script is injected.
- By default, the script is injected at a point called "document_idle". At this point, the document is not busy (
DOMContentLoaded
has fired, window.onload
may or may not have fired).
- As a result, the functions in the script may be overwritten immediately after declaration.
To inject a small script, I recommend to add the code directly to the Content Script:
var actualCode = '/* Code here (see below for inspiration) */';
var script = document.createElement('script');
script.appendChild(document.createTextNode(actualCode));
(document.head || document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
If you want to make sure that the method is not going to be overwritten, you can use Object.defineProperty
, to define an immutable property:
Object.defineProperty(document.documentElement, 'onkeydown', {
value: function() {},
writable: false, /* Cannot be overwritten, default false */
configurable: false, /* Cannot be deleted, or modified */
enumerable: true /* Does not really matter. If true, it's visible in
a for-loop. If false, it's not*/
});
The previously mentioned method is supported in Firefox 4+ and at least Chrome 5+. If you want to also support Firefox 2+ and Chrome 1+, you can play with the __defineSetter__
, to prevent onkeydown
from being defined:
document.documentElement.__defineSetter__('onkeydown', function(){});
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…