Tuesday, April 18th, 2006
DOM Builder: A nicer DOM
We all seem to hate the DOM API. It is painful to work with for sure. Some have thrown away DOM and instead relied on innertHTML and friends to get the job down. Others feel that "It’s always seemed a bit wrong and dirty to use innerHTML to manipulate or add content to a page. It’s not a standard (more of an agreement between browser manufacturers) and it doesn’t work on some browsers with certain mime-types while the core parts of the W3C DOM spec are implemented pretty damn consistently in most modern browsers. The problem is though that it’s realllllly long winded."
Dan Webb has put together DOM Builder, which looks a little like the Builders from Ruby (and from Groovy).
Example
The functions simply return a DOM node that you can append to whatever part of the document you like. Each function takes an number of arguments. The first argument can contain an object literal of attribute/value pairs if you need to specify attributes but if you don’t need attributes you can just leave it out. Otherwise it creates text nodes of any text you give it and appends any DOM nodes you give it. That’s it.
-
-
ar html = DomBuilder.apply();
-
-
var form = html.FORM(
-
html.DIV(
-
html.INPUT({type : 'text', name : 'email'}),
-
html.INPUT({type : 'text', name : 'password'}),
-
html.INPUT({type : 'submit'}),
-
)
-
);
-
-
document.body.appendChild(form);
-












Does it support CSS style attributes?
I think this has been around for quite a while in script.aculo.us:
http://wiki.script.aculo.us/scriptaculous/show/Builder
Why doesn’t someone write an innerHTML -> DOM converter utility?
That way you can just say something like:
myElement = getDOMFor(”…my markup…”)
getDOMFor takes the innerHTML as input and returns the DOM element. It may not wean people off using innerHTML but it would be a nice bridge.
David, interesting concept, although it is a bit like putting the carriage before the horse. What DOM methods teach developers is to stop seeing the HTML page as a massive string but as a set of nodes.
The technicalities of the function you mentioned are pretty tough, for starters you’ll have to validate the string if it is real HTML. It is not hard for easily nested elements but something like
<p>foo<strong>bar<span title="foo,baby">foo</span></strong>more foo</p>is a pain to match with regExp.This looks very similar to Mochikit’s DOM API.
David, why not just write a utility for converting XHTML to JS code which builds DOM using DOMBuilder, jquery or any other similar library?
XHTML parsing is quite easy with DOMParser/XMLDOM in FF/IE.
This should be faster then parsing XHTML every time on the client-side.
E: Yes, it is pretty similar to the thing in Mochikit although I’ve not looked into it in detail. I wrote this before I knew about the one in Mochikit but I have creditted Mochikit in my post and I thought it was valuable to release a standalone version for people that don’t use Mochikit.
David/Chris: I agree with Chris on the point of parsing DOM Nodes from a string. It’s a bit backward.
I wrote this partly because I don’t like dealing with strings of HTML in JavaScript. The DOM Builder code is more readable and even slightly more consise than an equivilent HTML string. HTML strings are often a bit nasty looking as you need to escape quotes and JavaScript has no nice facility for multi-line strings which makes it rather messy IMO.
innertHTML into innerHTML
ar html = DomBuilder.apply();
into
var html = DomBuilder.apply();
please.
David- I’ve writtena python script to convert xhtml to the mocikit DOMsyntax (which is strikiingly similar to this)
Here’s a blog post about it
ps. This ajaxy comment box is slow and annoying on firefiox…
Agree on Mochikit-independence. Mochikit does a good job, but requires 2 or 3 other files, I seem to recall around 40 or 50KB altogether, which is why I’ve been using my own tinny version of this approach.
[...] via ajaxian [...]
[...] ajaxian.com is reporting on a bloody nice DOM node builder. [...]