unobtrusive javascript, part 1: tabs

This week I decided to try applying the idea of unobtrusive JavaScript to Touring Machine. My JavaScript has been pretty unobtrusive already, mostly because I just haven’t gotten around to adding much client-side behavior, but I wanted to get an early start on taking the right approach.

The idea behind unobtrusive JavaScript is to keep “behavior” aspects of your web application separate from “semantics” and “presentation”. It’s roughly equivalent to the MVC approach, where:

  • model == HTML == semantics
  • view == CSS == presentation
  • controller == JavaScript == behavior

(Not coincidentally, an influential implementation of this idea was called Behaviour.js.)

There are a lot of advantages to this approach. In a development organization larger than Touring Machine’s, separation of concerns allows you to hire different people to focus on different aspects of the application. For me, a lot of the appeal is graceful degradation in browsers that don’t support JavaScript, particularly for the sake of accessibility.

So, okay: Let’s get the JavaScript out of our markup! There are only three script tags to fix:

  1. After each venue card, a script fragment creates a Control.Tabs object to manage the tabs.
  2. For each map we want to display, a script fragment calls TouringMachine.loadMap to load the map into a given div.
  3. Combining the two, each venue card includes a tab containing a map that should be loaded only when the user selects that tab. This is where the trouble begins.

But let’s start before the trouble.

Tabs

We used to create tabs with code like this after each tab set:


Using Prototype, we can replace all this code, evaluated piece by piece as the page is loaded, with an event-triggered loop in application.js:

Event.observe(window, 'load', function() {
    $$('.tabs').each(function(element, index) {
        new Control.Tabs(element);
    });
});

In something like English: After the page is fully loaded, we find all the elements with CSS class ‘tabs’, and create a Control.Tabs object for each one. Simple!

So there’s an easy transition to unobtrusive JavaScript. In the Control.Tabs model, by the way, the markup for each tab contains a link to the DIV that holds the tab’s contents. If a user doesn’t have JavaScript enabled, all of the content DIVs will be visible, and each tab just a link to that section of that page.

Next I’ll talk about adding maps to the page.

One Response to “unobtrusive javascript, part 1: tabs”

  1. Touring Mechanic » Blog Archive » unobtrusive javascript, part 2: maps Says:

    […] Touring Mechanic keeping Touring Machine up and running « unobtrusive javascript, part 1: tabs […]