Wednesday, April 4

you all who come here for things about real life can ignore this one as well.

I spent today mucking around with JavaScript again. Actually, it didn't feel anywhere near as unclean as I would've expected. In many ways, it seems like a decent language. There's even a kind of elegance to the DOM/CSS/JavaScript stack. If the relationships you're trying to model can be handled cleanly in HTML markup, then you get lots of nice things for free.

Maybe that's a big if, but to give a concrete example, I'm putting together an interface where the items to be manipulated can be in one of three panes on the screen at a given time. They need to display and behave differently in each pane. It turns out to be cake for the same list item to change styles radically depending on the class of its containing list:

<ul class="right" id="bucket">
  <li>Foo</li>
  <li>Bar</li>
</ul>

<ul class="left" id="platter">
  <li>Baz</li>
  <li>Bif</li>
</ul>

...can render as buttons with left and right pointing arrows, for example, just by setting the styles for ul.right li and ul.left li. You have to play with it a bit, but if your browser doesn't completely suck, it'll look pretty darn ok. And then you just do something like this:

var bucket = document.getElementById('platter');
var bucketItems = bucket.getElementsByTagName('li');

for (var i=0; i < bucketItems.length; i++) {
  bucketItems[i].onclick = listHandler;
}

And write listHandler to do the right thing based on context:

function listHandler () {
  var place = this.parentNode.className;
  switch (place) {
    case 'left':
      // appropriate action here
      break;

    case 'right':
      // you get the idea
      break;

    default :  return;
  }
}

Which is way easier than doing a lot of accounting on event handlers as you move list items around to different containers. (Which is what I was doing before, using a bunch of anonymous functions. Anonymous functions in JavaScript are neat, but all of that "well, I'm putting it over here so I have to make sure that when I click it it'll move back over here" logic gets fragile in a hurry.) You even wind up with list items which do nothing when clicked in a context where, say, the entire <ul> has an onclick - without having to set all those individual handlers to null. (Or at least you do in Firefox.)

I've got no idea how correct any of this is. There may be a much smoother way to assign a certain event handler to all elements of a given class, or what have you. It's not like I know the language, and I've treated this stuff as toxic for so long that I might as well have been living in a cave since around 1998, but it could all be much worse.

Postscript: If you haven't tried Firebug, you might want to try Firebug.