i am dustin diaz

a JavaScriptr...

boosh.

don't worry about it.

The "add a class name" JavaScript widget philosophy with "Fantasticulator"

There's a disturbing trend going around in JavaScript widget-making land that even I myself have been sentenced to being guilty as charged, and that is the view of "adding a class name" to invoke the behavior of some JavaScript widget. Of course this may not sound like that big of a deal and in retrospect it was a very cool idea which made it very simple to implement widgets blindly without having to write any real JavaScript yourself. The fact of the matter is, there can be some heavy side-effects that most intermediate developers don't want to pay attention to.

Examples of "adding the class name"

The implementation of this idea is simple. Let's say we want to make a new widget called Fantasticulator which is a new hip web 2.0 widget you can embed directly onto your webpage simply by adding the JavaScript library into the head of your document like so:

Embedding the Fantasticulator Engine

<script src='lib/js/fantasticulator.js'></script>
Oh and let's not forget to add our dependency files to really make this thing Fantastic!

Fantasticulator dependency files

<script src='lib/js/prototype.js'></script>

<script src='lib/js/scriptaculous.js'></script>

<script src='lib/js/jquery.js'></script>

<script src='lib/js/yahoo.js'></script>

<script src='lib/js/dom.js'></script>

Then to give your document ammunition to trigger the Fantasticulator all you have to do is add the class name of "fantacy" to any element in your page. See below for a demonstration.

Embedding your fantacies



<p><a href="#" class="fantacy">JavaScript Foo</a></p>

Why this is bad

Not to dismiss its conveniency, but it fails in performance, it's demanding, and it's a high risk for conflicts.

Performance

Without looking under the hood of any library that requires you to add a class name to your document to receive the super-cool functionality, it's fairly obvious what needs to get done. Like any other getElementsByClassName function, you need to supply a class name, a tag name, and a root node. And to generalize things to a base level that gives the implementer the most amount of flexibility, you must start at the document root then crawl all the way to the bottom checking each and every node for a class name. To say the least... that's bad. Client-side performance of the "add a class name" philosophy is reason-nuf (reason enough) to avoid implementing this style of widget-making.

Demanding

Generally, you want to avoid contracts that force the implementer to muck with their HTML. But like I said, albeit its downright convenient method of adding behavior for developers, you shouldn't make this assumption that access to snippets of HTML is going to be possible. But rather it should be a best practice to target the elements yourself which gives you the freedom of optimization, and then pass those elements to the widget machine.

Risky Business

In any case, it gets a bit risky when libraries are dependent on a class name existing in the markup. Especially in the era of web 2.0 JavaScript Foo, you may run into issues of class names getting overridden by replacement or removal functions. If Developer Joe runs Utils.nukeClasses() before Developer Schmoe runs Fantasticulator.init(), you've got a conflict.

Anyway, here's what you do

By far the simplest solution to put into your next Fantasticulator widget is to accept an argument where the developer is allowed to pass in elements. Yes, it requires more work for the developer, but in the end it's faster, less demanding, and safer.

Pass the buck



<script>

...

var parent = document.getElementById('foo');

var elements = parent.getElementsByTagName('a');

var Fantacy = new Fantasticulator(elements);

Fantacy.init();

...

</script>

this is who i am

Hi, my name is Dustin Diaz and I'm an Engineer @ObviousCorp. Previously @Twitter, @Google, and @Yahoo, author of Strobist® Info co-author of JavaScript Design Patterns, co-creator of the Ender JavaScript Framework, a Photographer, and an amateur Mixologist. This is my website. Welcome!

On this site I write about JavaScript. You can also follow along with my open-source work on Github.

This site is optimized and works best in Microsoft Internet Explorer 6.