• Home
  • Flailing Wildly
  • Résumé
  • Design
  • Code
  • Wishlist
  • About Me

Flailing Wildly
Too much straw, not enough camel.

Introducing DOMBuilder

by Ryan Parman • February 27, 2009 • Code, Projects • 3 comments

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.

Ryan Parman

Ryan Parman is an entrepreneur, open source evangelist and passionate usability advocate currently living in Seattle. He is the founder and visionary behind SimplePie and CloudFusion, co-founder of WarpShare, member of the RSS Advisory Board, and is currently with Amazon. Ryan's aptly-named blog, Flailing Wildly, is where he writes about ideas longer than 140 characters.

« 25 random things about me
Those kids and their Wiis »

Discussion

non

March 21, 2009

Interesting!

Great work. Thanks.

rpx9b914402504c6d83c9bfb2dcf8605fea

September 19, 2009

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

thor918

September 26, 2009

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]);
    }
}

Have your say

Login with your favorite account to leave a comment!   

Blog search

Archives
  • 2010 (7)
  • 2009 (7)
  • 2008 (12)
  • 2007 (8)
  • 2006 (18)
  • 2005 (57)
  • 2004 (104)
  • 2003 (103)
Categories
  • Apple (43)
  • Browsers (55)
  • Code (57)
  • Creating Websites (31)
  • Design (5)
  • Digital Media (3)
  • Family Life (10)
  • Just for Fun (25)
  • Music (5)
  • Personal (32)
  • Political (12)
  • Projects (44)
  • Software (60)
  • Syndication (28)
  • Technology (75)
  • Tutorials (5)
  • TV and Movies (16)
  • Video Games (5)
  • Website (62)
  • Work and Business (3)
  • Writing (4)
Socially-aware
  • Twitter
  • Facebook
  • Flickr
  • Last.fm
  • Glue
  • YouTube
  • Delicious
  • LinkedIn
Claim to fame
  • Amazon Web Services
  • WarpShare
  • CloudFusion
  • SimplePie
Legal mumbo-jumbo

All ideas, opinions and comments I post are my own and are in no way affiliated with anybody I work with. If you quote and/or reprint something I've written or said, please direct folks back to this site as a form of attribution. I promise I'll do the same for you. Unless otherwise noted, all content on this site is copyright © 1979–2010 Ryan Parman. Powered by Rocket Sauce.