Unobtrusive Jump Menus Using JavaScript

An Emerging Paradigm

The more I learn about the DOM and UJS, the more I become fascinated with the direction that client-side scripting is headed. Years ago I vowed to use JavaScript very minimally, if at all. I hated the fact that I had to write two or three browser-specific implementations of the same code. I also hated how nearly everything had to be coded inline. With growing support of the DOM, times are starting to change — and so are my feelings about JavaScript.

Old School Jump Menus

Here is a simple script that I used frequently in web applications to make jump menus. A jump menu, in this context, is a <select> form element that, when an option is chosen, redirects you to another page/website.

<select onchange="if( this.options[this.selectedIndex].value != '' ) location.href=this.options[this.selectedIndex].value;">
    <option value=""></option>
    <option value="http://google.com/">Google</option>
    <option value="http://yahoo.com/">Yahoo!</option>
    <option value="http://ask.com/">Ask.com</option>
</select>

As you can see, the JavaScript is coded inline with the XHTML. In this particular example it doesn't seem too messy, but what if you needed to add three or four events to the same element (i.e. onmouseover + onmouseout + onclick for a customized button)? It would be much easier to manage if you could tuck all that code away into the <head> section of your XHTML or, better yet, in a separate file altogether.

A New Perspective

The concept of Unobtrusive JavaScript is to do what CSS does with styles, except with behaviors. In the same way that CSS separates design from content, UJS lets us separate behavior from content. This practice provides us with cleaner, faster loading XHTML, graceful degradation, and easier to manage code.

Take the jump menu script, for example. When coded unobtrusively, the XHTML looks like this:

<select id="jm1" class="jumpmenu">
    <option value=""></option>
    <option value="http://google.com/">Google</option>
    <option value="http://yahoo.com/">Yahoo!</option>
    <option value="http://ask.com/">Ask.com</option>
</select>

Notice that the jumpmenu class was assigned to the <select> element. I've also added a unique ID so the script can determine which URL should be used when an event is triggered.

To maximize accessibility for users that have JavaScript disabled, you could wrap the jump menu in a form, add a submit button, and set the action to a page that redirects them without using JavaScript. For the sake of simplicity, this example does not show this.

Now we have to write the code to turn all <select> elements with the jumpmenu class assigned to them into jump menus.

<script type="text/javascript">
    function initJumpMenus() {
        // Turns all <select> elements with the 'jumpmenu' class into jump menus
        var selectElements = document.getElementsByTagName("select");
        for( i = 0; i < selectElements.length; i++ ) {
            // Check for the class and make sure the element has an ID
            if( selectElements[i].className == "jumpmenu" && document.getElementById(selectElements[i].id) != "" ) {
                jumpmenu = document.getElementById(selectElements[i].id);
                jumpmenu.onchange = function() {
                    if( this.options[this.selectedIndex].value != '' ) {
                        // Redirect
                        location.href=this.options[this.selectedIndex].value;
                    }
                }
            }
        }
    }

    window.onload = function() {
        initJumpMenus();
    }
</script>

When the page loads, the script populates a list of all <select> elements in the document using the initJumpMenus() function. Then it adds the appropriate onchange event to those elements that are assigned the jumpmenu class. Simple.

The Benefits of UJS

That's a lot more code than the original example had. At first glance, it doesn't seem like it's worth all of the extra steps. With UJS, the initial investment usually seems a bit more than the return. But what if we wanted to add another jump menu? Simple. Add another <select> element with the jumpmenu class and a unique ID. There's no more JavaScript to write. Best of all, the code becomes reusable if you include it from a separate file.

Similar to the way you can manage the style of a class using CSS, you can manage the behavior of a class using UJS. In my opinion, that's much better than the traditional method of going page to page and copying and pasting inline code snippets.

Author avatar

About the author

New Hampshirite building web apps in Florida. Creator of Surreal CMS, Postleaf, and DirtyMarkup.

Need to get in touch? Catch me on Twitter.