Unobtrusive JavaScript with Prototype and Behavior

If you are familiar with web application development you may already be familiar with the Model-View-Controller (MVC) design pattern. The MVC pattern aims to separate your server side business logic from your presentation code from your data model. The by-product of web applications are the HTML, CSS, and JavaScript pages generated and delivered to the client browser. Historically in the early Web 1.0 days, a web page’s content, style, and behavior would all be intertwined and glued tightly together in the HTML, do you remember the font tag? Somewhere along the way to the Web 2.0 network, developers opted to remove the style attributes from the content by using Cascading Style Sheets (CSS) classes.

CSS allows you to create style classes whose concern is purely a way to describe the size, font, color, and look of whatever content that uses the class.

.makeMeBeautiful {
  color: #00248F;
  text-decoration: underline;
  background-color: #FFFFFF;
  font-size: 1.1em;
}

To apply a CSS class on an HTML element you use the class attribute.

<div class="makeMeBeautiful">Hello, World</div>

The idea behind Unobtrusive JavaScript (UJS) is to remove JavaScript events, such as onclick and onmouseover, from the content in the same fashion as the style attribute. Unobtrusive JavaScript uses the class and id attribute of HTML tag elements to find and assign JavaScript events in a inconspicuous fashion, just as with CSS.

If you think of the HTML content as the Model, the CSS stylings as the View, and JavaScript behaviors as the Controller of MVC, then it makes perfect sense to remove all traces of style attributes and JavaScript events from the HTML.

Unobtrusive JavaScript with Prototype

Traditionally if you wanted to add a JavaScript onclick event to a HTML element you would do so by adding the onclick attribute. Unobtrusive JavaScript recommends that you instead find the tag by the class or id attribute and assign the even programmatically.

// Logic to execute when the end user
// clicks the element
function myOnClickFunction(elem) {
  alert(elem);
}

// Register the onclick event for all elements
// the given class name
window.onload = function() {
  // Find all elements that use that given CSS class
  var elements = document.getElementsByClassName("makeMeBeautiful");
  elements.each(
    function(e) {
      // Assign the onclick method to the element
      Event.observe(e, "click", myOnClickFunction);
    }
  );
}

Note that the above JavaScript code works only when the Prototype JavaScript library is made available.

If your need to add Unobstrusive JavaScript events for a few tag elements and are already using Prototype then the above code will suffice.

Unobtrusive JavaScript with Behavior

For more restrictive selection process of the HTML elements to apply JavaScript events you can use the Behavior JavaScript library. The Behavior JavaScript library is a lot easier and more powerful way to add behavior to HTML elements than Prototype. With the Behavior library you define an associated hash map literal object thingie where the keys are CSS selectors and the value is an initializing JavaScript function. In the initializing function you can add any onclick, onmouseover, onchange, onsubmit, onfocus, onblur, onwhatever event.

var rules = {
  '.makeMeBeautiful' : function(elem){
    elem.onclick = function(){
      alert(elem);
    }
  }
};

Behaviour.register(rules);

The power of the Behavior library is that you can create the behavioral rules using CSS selectors to choose the tag elements for which to apply a given set of JavaScript functionality. Both the Prototype and Behavior code shown up to this point will apply the JavaScript onclick behavior on all elements that use the given CSS class. With the Behavior library you can use CSS selectors to restrict what elements to apply the behavior to. For example, to apply the onclick behavior only for div elements you can use the following rule.

var rules = {
  'div.makeMeBeautiful' : function(elem){
    // Your code here...
  }
};

The idea behind Unobtrusive JavaScript is to separate the HTML, CSS, and JavaScript according to responsibilities in a similar fashion as the MVC design pattern suggests. UJS also helps in the maintenance of large sites and it allows for graceful degradation.

Related posts:

  1. JavaScript FX
  2. Rounded Corners With Rico
  3. JavaScript StackTrace With The console Object
  4. Twelve Elements of JavaScript Style
  5. Dynamically Create HTML Elements with JavaScript
  6. Put JavaScript To Sleep


7 Responses to “Unobtrusive JavaScript with Prototype and Behavior”

  • Keith Says:

    You blog is truely outstanding!! Thankyou, there’s an enornmous wealth of great stuff for a rails noob like myself. I’ve already been reading this far too long at work, so i must leave now, but i’ll be back!!

  • TechKnow Says:

    @Keith – Thanks for your comments, I appreciate that.

  • Carter Says:

    I’m curious why you need to combine Behavior with Prototype. How does the added bonus of providing event rules in an object literal outweigh Prototype’s built in CSS Selectors? Is it really worth an additional 8k?

  • TechKnow Says:

    @Carter – I am sure it wasn’t clear but I wasn’t trying to promote using both Behavior and Prototype! You should use either/or. This was supposed to be like a mashup tutorial detailing how to achieve unobtrusive JavaScript in either Behavior or Prototype. Thanks for the comment!

  • Carter Says:

    oops– not sure how i missed that :p Thanks for the writeup, I’m all for it then!

  • :murb: Says:

    Behavio(u)r doesn’t seem to exist anymore, and at the root site [1], I found Ben Nolan (I suppose he was the author of Behaviour) referring to jQuery [2,3], which seems to do more or less the same…?

    [1] http://bennolan.com/
    [2] http://bennolan.com/?p=66
    [3] http://jquery.com/

  • krishna Says:

    Thanks for the write up on behavior. Its was very useful

Leave a Reply