Note: Recent tests lead me to believe that this does not work properly in IE7. I still have to look into it.
So some buddies of mine asked me a few days ago if I would build them a web application to help them track runs in EVE Online. Seeing as how it would both give me something to do and let me start a fresh web project not riddled with code I wrote when I didn’t know any better, I agreed. One thing I wanted to do correctly from the start was JavaScript DOM mutations. Back when I didn’t know any better I used innerHTML like it was thrown in free because I waited for more during a Billy Mays infomercial (Hi, Billy Mays here for Internet Explorer! Why conform to all those pesky internet standards…).
As I started writing client-side DOM mutation functions for AJAX callbacks, I started abstracting the logic into simple DOM functions. After awhile I realized that the only way I was going to be truly happy was by using a JavaScript parser that could take a string of HTML markup and convert it to a DOM sub-tree. This way I could have templates of HTML stored server-side, send those templates back with the proper information when requested by the client, and the client can just parse the HTML string and inject it into the DOM as needed. I initially set off to write one, but then thought that somebody else probably already wrote one (this is, after all, the internet). After a bit of googleing, I found that John Resig had already modified one made by Erik Arvidsson to seemingly do exactly what I was looking for. I gave it a spin and it did most of what I wanted, but was lacking one feature that, after taking a bit of time to figure out the parser’s logic, I added to it.
I really only added about three lines of code to make it work. Originally, the HTMLtoDOM function did not actually inject the parsed HTML into the DOM at the given node, it would just blindly inject it into the document body. Also, the original function would only seem to inject the parsed HTML into the DOM, or return a complete DOM tree, starting at an HTML root node. I thought it would be more useful if it returned the parsed DOM sub-tree without actually injecting it into the DOM, that way you could still do whatever you wanted with it (element swaps/clones/etc. outside the parser’s logic). This is done by returning the first child of the parent DOM object that marks where the parsed HTML is to be injected. By supplying the function with a garbage div [HTMLtoDOM(htmlString, document.createElement("div"));], the parser injects the parsed HTML as a child of the bogus div that was created for the parser, and returns that element. Since the bogus div is never injected into the actual page DOM, you’re free to do whatever you want with this DOM sub-tree before your attach it to the page DOM.
Here is the JavaScript file: htmlparser.js
The original can be found at John Resig’s blog
I haven’t tested that the other functions still work because I never use them. I just left them in for completeness, but there’s no reason that they shouldn’t work. Modifications were only made to the HTMLtoDOM function.