On the Inelegance of Current JavaScript Paradigms

As cool as unobtrusive JavaScript is for building the behavioral layer, it's nevertheless based on some pretty kludgy foundations, especially when contrasted with CSS's rather elegant method of declaratively building the presentation layer.

Kludge #1: Waiting for DOM load.

It seems unavoidable. If you want to be unobtrusive, there will be a delay before your functionality is available. Furthermore, DOMContentLoaded and friends don't truly solve the problem. Interestingly, a parallel problem exists in the CSS world: the FOUC (Flash Of Unstyled Content). FOUC is generally not a problem in modern web clients. I wish I could say the same for the "flash of behaviorless content" problem.

Kludge #2: Procedural DOM traversal and event attachment.

Why do I have to seek out the elements that interest me and add behavior, element by element? What a pain. On sufficiently complex pages this means walking the entire tree. If you add new elements as you walk the tree, hall-of-mirrors-style infinite loops and other pitfalls plague you. If innerHTML gets added during the course of the page's life, you have to go back and re-walk those parts of the DOM, re-attaching events as needed. Once again, contrast this with CSS, where the user agent abstracts away the traversal and the attachment of styles, allowing you to declare once--up front--which elements get which styles. Pity we can't do it this way for the behavior layer too.

So what?

Of course these are well known problems. Such is the hand we've been dealt, and tools and techniques exist that make these problems less painful, so why the fuss? In my mind anyway, leaky abstractions on top of kludges aren't an ideal state of affairs, and so I rant. But I also wanted to establish a little background for a future post where I'll describe some tools we're about to deploy on sun.com that, in certain instances, avoid these problems altogether.

[Update]: I've posted a followup with a bit of information about how our new library works.


Of course, I'll be interested in what you are deploying on sun.com, but it sounds like you're wishing for XBL2.


Posted by Sean on February 05, 2008 at 11:35 AM MST #

Indeed. I'm not hugely familiar with XBL, but something tells me widespread browser support isn't on the horizon. I'd love to be proven wrong though.

Posted by Greg on February 05, 2008 at 12:26 PM MST #

jQuery (http://jQuery.com) lets you attach behaviors to DOM elements using CSS selectors:

$('div.article > a.source').click(function(){
// take the a.source's href value and use it to load via ajax
$('div#content').load( $(this).attr('href'), '' );

// preventDefault() and stopPropogation()
return false;

This is completely unobtrusive, it will take a set of normal anchors, attach onclick handlers that make ajax requests with the existing href urls, and stop the default click behavior of the anchor.

Posted by Aman Gupta on February 05, 2008 at 05:01 PM MST #

Well, you are right, however there is a way around the problem of having to traverse the whole DOM for the elements you want to add behaviour to: event delegation. As most events (with onkeypress being the exception) do get reported up the hierarchy, you can add one listener to a parent node and use the event object to find out what was clicked: http://icant.co.uk/sandbox/eventdelegation/

Posted by Christian Heilmann on February 05, 2008 at 08:29 PM MST #

@Aman Gupta: JQuery looks like a great library. If I click on a div.article > a.source element before $(document).ready() fires, will it work? Not familiar enough with JQuery internals to answer that one for sure.

@Christian Heilmann: Shh, you're going to spoil the surprise!

Posted by Greg on February 06, 2008 at 02:36 AM MST #

[Trackback] On the Inelegance of Current JavaScript Paradigms - Gregory Reimer's Weblog nice site design; haven't

Posted by fractalnavel on February 06, 2008 at 08:40 AM MST #

as Chris already noted "event delegation" is the key here, but I believe I have even got a step forward that by also completely avoiding "onload" and maintaining the beauty of being able to do that through CSS3 Selectors.

Here is the blog, at Peter Michaux site, where I presented a proof of concept some time ago covering slightly different approaches:


And here is the almost finished work (test code) on event delegates:


I am also attaching handlers with CSS3 Selectors, but the best is that this code allows me to do it, as you said, "up-front", so I don't need an "onload" or similar to attach functionality (events) to page component early in the load process.

This will drastically shorten the exposure time that the UI may have, and give a perfect separation between presentation and functionality.

This has also several advantages, like for example newly created elements matching the same selector will automatically acquire the same behaviors.

The documentation is still missing but the code is working as expected on all browsers I could test. There is a trick with non bubbling events, but I hope to have solved also that one. It can surely be improved but testing and feedback is still missing.

To get the described environment requires two scripts "nwevents.js" and "nwmatcher.js" both of which where published in Google Code in October last year.

I am sure you can give me some good technical advice about this idea.


Posted by Diego Perini on February 09, 2008 at 08:27 AM MST #

Post a Comment:
Comments are closed for this entry.

My name is Greg Reimer and I'm a web technologist for the Sun.COM web design team.


« July 2016