Published:

27 Feb 2009

Categories:

Code
Projects

Comments:

3 total

Introducing DOMBuilder

I hate the DOM. Actually, I take that back. I love the DOM, but I hate the fact that generating DOM nodes in JavaScript is so verbose and unintuitive. You need to construct a new element, then add properties, then construct a child element, then add properties, then append the child to the parent, and the parent to whatever DOM object you want that’s already in the page.

A few years ago I discovered Builder.node(), a component of Scriptaculous. The problem is that Scriptaculous relies on Prototype, and both are HUGE JavaScript libraries. Later I moved to Moo.fx/MooTools, then I didn’t do much JavaScript for a while, then I started doing a lot with YUI, while sprinkling a little jQuery around here and there. None of these other frameworks had an equivalent to Builder.node(), and again, that sucks.

So last night, I wrote a small JavaScript class to handle this very thing. Introducing DOMBuilder. DOMBuilder is small, fast, and doesn’t depend on any other JavaScript frameworks meaning that it’s easy to use in any project where you need to construct nested DOM elements. The fully commented debug version clocks in around 3k. The minified version is 739 bytes. With gzip compression, it squeezes down to a mere 393 bytes.

It’s not quite as terse or elegant as I’d like (yet), but it’s a good result for about 2 hours of hacking.

Examples

Here’s the HTML we want to generate:

<div class="location_select_control">
	<a href="" class="location_select_label">
		<label>This is my label</label>
	</a>
</div>

Here is how we’d do it with the standard DOM:

control_div = document.createElement('div');
control_div.className = "location_select_control";
control_link = document.createElement('a');
control_link.href = "";
control_link.className = "location_select_label";
control_label = document.createElement('label');
control_label.innerHTML = "This is my label";
control_link.appendChild(control_label);
control_div.appendChild(control_link);
document.body.appendChild(control_div);

Lastly, here’s how we’d do it with DOMBuilder:

document.body.appendChild($dom('div', { class:'location_select_control' }).child(
	$dom('a', { href:'', class:'location_select_label' }).child(
		$dom('label').innerHTML('This is my label')
	)
).asDOM());

Download

This code is BSD licensed, so feel free to use it in personal or commercial projects. You can download it from Github.


Comment by non 21 Mar 2009 at 2:33 pm 

Interesting!

Great work. Thanks.

Permalink

Comment by rpx9b914402504c6d83c9bfb2dcf8605fea 19 Sep 2009 at 10:29 am 

This is AWESOME, I haven’t seen something like it in a long time. Thank you!

Permalink

Comment by thor918 26 Sep 2009 at 3:24 am 

how about changing it a bit to handle internet explorer style attribute?

// Loop through the hash (i.e. associative array, key-value pairs)
for (var key in attr) {

// Handle ‘class’ differently for IE.
if (key.toString() == ‘class’) {
// Add it to the element
this.element.className = attr[key];
}else if( (key.toString() == ’style’) && (this.element.style.cssText!=undefined) ){
// Handle ’style’ differently for IE.
this.element.style.cssText=attr[key];
}else {
// Add them to the element
this.element.setAttribute(key, attr[key]);
}
}

Permalink

Leave a comment