document.write, I pity the fool. But also suggest ways in which he can better himself

This post has been updated since i first wrote it, originally I suggested using innerHTML to insert the content, the problem there is that scripts added in that way do not execute.

Document.write has been causing me pain this week, prepare for a small amount of constructive venting.

You might remember the Write method from those days you were learning how to write JS, whack it in and it writes whatever you give it to the screen. That’s fine but the problems occur when you think a bit more about how it does that and almost always you should be using something else.

If I write a script using Write and include it in the page body, any writes will be made in that same position. That makes sense as it’s part of the source parse and script evaluation, it’s where the browser is up to.

What it totally screws up is when I then want to make your damn 3rd party script deferable / lazy loadable! Why? Because once the page has been loaded any subsequent calls to document.write will replace the entire page.

Fix document.write

We can overwrite the document.write function but the difficulty is what with. My best guess at the moment is that;

  1. Before the page is loaded write calls are performed normally
  2. Once loaded, we replace Write with an new function
  3. When called we append the content to the body element.

Example with jQuery.

 
var fDocumentWrite = function(str,bOverrule){ 
if (bOverrule === true) { 
//superwrite is a reference to the original document.write function 
fSuperWrite.call(this,str); 
} 
else { 
jQuery(document.body).append(str); 
} 
}; 

Why not something else?

  • We cannot be sure of the content, if it’s text it could just be a text node that we append, but if it’s HTML it needs to be parsed and each created… Or shoved in a container anyway.
  • We can’t use innerHTML, doing so on the body will destroy event hooks appied to that code, innerHTML replaces all that content so it’ll also be slow. Also scripts dont execute when inserted using innerHTML.
  • Don’t defer the script? It’s safest, but with a decent amount of testing we can make this safe enough. Though there will always be a vender somewhere crazy enough to break anything

If you have a better fix for this then let me know, I’ve about four scripts I want to defer and it’s only Wednesday.

In summary, don’t use document.write, Doug Crockford says not to do and, even though he has a beard, you should trust him on this.

Filed under: JavaScript