« 3-2-1 Marketing!
First Look: Windows 7 »


Making Document.Write Actually Work

I think most people know better than to use document.write to emit content into a web page, but if not here are a couple reasons:

  • document.write does not work in XHTML.
  • If document.write is executed after the page has finished loading, it will overwrite the entire page.
  • document.write executes when it is encountered, it cannot inject a given node point.

The bottom line is that document.write sucks, and nobody should use it. However, almost every 3rd party analytic's vendor uses document.write in their tracking scripts.

These are usually iframes or script references you embed in your code, and then the vendors inject whatever they feel they need into your page.

I recently made some modifications to a page to dynamically load these 3rd party references after the rest of the page finished. However, doing that caused the embedded document.write calls to overwrite the entire page.

Luckily, with JavaScript, it is easy to replace browser implemented functions with your own function, and document.write is no exception:

document.write = function(args) {

    var dwNode = document.createElement('DIV');

    dwNode.innerHTML = args;

 

    document.body.appendChild(dwNode);

 

    // Script nodes in innerHTML won't run unless we eval them

    var runScripts = function(e) {

        if (e.nodeType != 1)

            return;

 

        if (e.tagName.toLowerCase() == 'script') {

            eval(e.text);

        }

        else {

            var n = e.firstChild;

            while (n) {

                if (n.nodeType == 1)

                    runScripts(n);

 

                n = n.nextSibling;

            }

        }

    };

 

    runScripts(dwNode);

};


This replacement document.write is called whenever the vendor code calls document.write. This code actually creates and injects a DIV into the DOM, and then eval's any embedded script tags. The script eval code was found on the internet after I discovered that script tags within innerHTML do not work.

This works well (Tested in IE6 and FireFox), and I was able to defer the loading of the vendor code until after the page has finished rendering, causing a nice improvement in the end-user experience.

Just make sure you place this in an include file, or in your page before any code that will make calls to document.write run.

Posted by Jonathan Holland on 4/29/2009.

Tags: Tips-and-Tricks   Javascript   Document.Write

Comments:

Comments are closed on this post.