OdeToCode IC Logo

Readable DOM Ready Event Handlers

Monday, March 26, 2012

One reason some people don't like JavaScript, I think, is because idiomatic JavaScript favors fewer keystrokes and CPU cycles over readability. There is a large amount of script code that is hard to read, and even harder to maintain and change.

Take, for example, the following snippet. I think this represents a typical DOM ready event handler with jQuery.

$(function () {
    $("#warning").dialog({ autoOpen: true });
    $("#openDialog").click(function () {
        $("#warning").dialog("open");
    });
    $("#submit").click(function () {
        $("#warning").dialog("close");
    });
    $("#names").autocomplete({
        source: ["Foo", "Bar", "Baz"] 
    });
});

It's a wall of text written in the get in, get done, and get out style. The code requires some concentration to see what is happening inside.

I think the code improves after lifting out the nested, anonymous functions.

$(function () {
    var warning = $("#warning");

    var openDialog = function () {
        warning.dialog("open");
    };

    var closeDialog = function () {
        warning.dialog("close");
    };

    warning.dialog({ autoOpen: false });   
    $("#openDialog").click(openDialog);    
    $("#submit").click(closeDialog);       
    $("#names").autocomplete({
        source: ["Foo", "Bar", "Baz"] 
    });            
});

And to take the idea one step further, here is a pattern I'm going to try and follow over the next few weeks: initialize, implement, act

$(function () {

    var warningDialog = $("#warning");
    var openButton = $("#openDialog");
    var submitButton = $("#submit");
    var nameInput = $("#names");
    var inputValues = ["Foo", "Bar", "Baz"];

    var openDialog = function () {
        warningDialog.dialog("open");
    };

    var closeDialog = function () {
        warningDialog.dialog("close");
    };

    warningDialog.dialog({
        autoOpen: false
    });
    nameInput.autocomplete({
        source: inputValues
    });
    openButton.click(openDialog);
    submitButton.click(closeDialog);
    
});

 

The initialize section initializes variables, and tries to lift as many selectors as possible out of the code that follows. The implement section contains functions and other implementation details for the behavior of a page. The act section is the place for wiring up event handlers, creating widgets, and kickoff any data binding for the page.

The end result is verbose, but I've already found it easier to read and change as the requirements shift.

Thoughts?