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>