Dive Into Greasemonkey

Teaching an old web new tricks

4.16. Post-processing a page after it renders

Because of how Firefox stores a rendered page internally, large changes to the page's DOM should be done after the page is finished loading. You can delay processing of a function using the addEventListener function.

Example: Replace an entire page with custom content

var newBody = 
'<html>' +
'<head>' +
'<title>My New Page</title>' +
'</head>' +
'<body>' +
'<p>This page is a complete replacement of the original.</p>' +
'</body>' +
'</html>';
window.addEventListener(
    'load', 
    function() { document.body.innerHTML = newBody; },
    true);

Looking closely at this code, you might naturally wonder why it works at all. I am declaring an anonymous function to pass as the second argument to window.addEventListener, which accesses the newBody variable defined in the outer function. This is called a “closure”, and is perfectly legal in Javascript. In general, an “inner” function defined within an “outer” function can access all of the outer function's local variables -- even after the outer function finishes executing. This is a very powerful feature that makes it possible to create event handlers and other functions that contain data structures constructed at runtime.

[Tip]

Zapping and replacing document.body.innerHTML does not change everything about the page. Anything defined in the <head> of the original page will still be in effect, including the page title, CSS styles, and scripts. You can modify or remove these separately.

Real examples

← Setting an element's style
Matching case-insensitive attribute values →