Please note that this page is being regularly updated as the script matures. Please check out the changelog to see what’s been added since it’s first release.
This is a solution to a niche problem. But even niche problems need solutions. A while back I started serving my pages with the application/xhtml+xml MIME type (in other words, as XML not HTML). The trouble was that all of the third party scripts on my site that used
document.write() to output their content stopped working. (To learn more about this issue read: Does document.write work in XHTML? and Why document.write() doesn’t work in XML.)
The solution isn’t as pretty as I had originally hoped, but it works.
I then toyed around with an early version of the script below and it was a lot more elegant than it is now. It was more elegant because every time a document.write was called it checked to see how far along the DOM was in being built by counting the number of script tags in the page. It then dumped its contents at the last known script tag’s position. Very clean. I wish I could have used that. It’s just that it only worked in text/html mode. As soon as I switched MIME types to application/xhtml+xml, the parser stopped cooperating and everything ended up bunched together at one location (the first script tag’s position). That’s because when using the text/html MIME type you’re in the standard DOM where script tags are parsed as the DOM is being built. Not so with application/xhtml+xml. The DOM is built first and then all scripts are run afterwards. The code that’s being executed has no idea where it’s being called from in the DOM (because in real XHTML you’re not supposed to run scripts that adjust the DOM directly in the body of the document) so there’s no reference for me to point to and say “build your nodeset here”. So seeing as how there was a huge disconnect between the scripts themselves and where they were supposed to dump their contents, I had no choice but to take the route that I took.
The code supports multiple script tags as well as script tags with multiple document.write()s, something I couldn’t have hoped to support in the first two tries. The code below basically does the following:
I suppose I could cut out the need for step four by identifying the script tags by the contents of their
src attributes, but for now I’m just happy to get this thing working. Maybe in the next version. ;-)
So far I’ve tested it on Firefox 1.5(PC), IE 6(PC), Opera 8.5(PC), IE 5.2(Mac) and Safari 1.3.1(Mac) and they all seem to work fine. Take her for a spin and let me know how it works for you!
<script src="DocumentWriteOverride.js"></script> <script> window.onload = DocumentWriteOverride.Show; // of course you can bind it however you wish as long as it's on load </script>
Read more from the archive.