InfoQ

News

AJAX developers continue migrating to unobtrusive JavaScript

Posted by Matthew Bass on Jun 24, 2008 01:31 PM

Community
Java
Topics
Javascript
Tags
AJAX
Unobtrusive JavaScript is an emerging technique that separates JavaScript from HTML markup. This is quite similar to the separation between styling and HTML that came about with the creation of CSS in the late 90s. For example, obtrusive JavaScript would add an onClick handler directly to an input field like this:
<input id="field" onclick="alert('hello')" />
Unobsutrive JavaScript waits until the page has finished loading before hooking up the event handler to the input field:
<script type="text/javascript">
Event.observe(window, 'load', function() {
Event.observe($('field'), 'click', function() {
alert('hello');
};
});
</script>

<input id="field" />

This keeps the HTML (our input tag in this example) clean and provides the developer with a single point of reference for debugging JavaScript code. Unobtrusive JavaScript is typically stored in external .js files as opposed to being embedded inside <script> tags in the HTML page itself. While the unobtrusive example here takes up more lines of code, larger blocks of JavaScript will generally end up being clearer and more concise when made unobtrusive.

Some other benefits of unobtrusive JavaScript include:

  • Separation of concerns: the behavior layer is separated from the content and presentation layers
  • Easier handling of browser inconsistencies
  • Concise code that's easier to read

When used with open source libraries like Prototype, unobtrusive JavaScript gets even easier to create. There are even frameworks specifically designed for taking obtrusive JavaScript and making it unobtrusive.

Low Pro, for example, adds several useful helper functions to Prototype, dramatically improves access to the browser's event model, and provides a behavior library that makes it a breeze to hook up unobtrusive triggers. Our previous example can be written in Low Pro like this:

<script type="text/javascript">
Event.addBehavior({
'input#field:click' : function(e) {
alert('hello');
}
});
</script>

<input id="field" />

Behaviors are automatically hooked up after the page finishes loading. Additional behaviors can be added using CSS selectors to pick elements for triggering.

With the number of AJAX-enabled web sites steadily increasing, JavaScript is becoming a much larger part of web application development. Keeping JavaScript unobtrusive makes it much simpler to develop flashy features. It will also make future maintenance of these web sites much easier and more cost effective.

Good viewpoint by Michael Minella Posted Jun 24, 2008 2:42 PM
Of course... by Francois Ward Posted Jun 24, 2008 5:09 PM
Harder to debug by Gabriel Ka. Posted Jun 25, 2008 1:07 AM
Re: Harder to debug by Francois Ward Posted Jun 25, 2008 6:44 AM
Re: Harder to debug by Bruno Vernay Posted Jun 25, 2008 7:22 AM
Clearer but slower by Luis Fernando Planella Gonzalez Posted Jun 25, 2008 7:30 AM
XBL 2.0 meant to solve the issue... by Sergey Ilinsky Posted Jun 25, 2008 8:31 AM
Re: XBL 2.0 meant to solve the issue... by Bruno Vernay Posted Jun 25, 2008 9:34 AM
  1. Back to top

    Good viewpoint

    Jun 24, 2008 2:42 PM by Michael Minella

    Good comparison to the HTML and CSS of previous years. For those who are interested, I have an in depth tutorial on unobtrusive JavaScript using prototype. You can find it at:

    http://www.michaelminella.com/javascript/unobtrusive-event-handling-with-prototype.html

  2. Back to top

    Of course...

    Jun 24, 2008 5:09 PM by Francois Ward

    Of course, half the reason people are moving to unobstrusive javascript is because all of the good toolkits use it, and not very often because of a conscious decision. Not that its a bad thing mind you! Especially with toolkits who automatically call an initialization method with a certain signature, you don't even need ANYTHING beyond the script tag that imports your script in the html... pretty slick.

  3. Back to top

    Harder to debug

    Jun 25, 2008 1:07 AM by Gabriel Ka.

    The html is much cleaner with these kinds of technics. But A web page becomes much harder to debug. - Where (the hell) the event is added? And where is it initialized? - How to be be sure that you do not add an event listener that goes against another one? - How do I know which listener exists for this event? - How do I know the events that start this listener? etc. It increases javascript complexity, adds magic to code. It means that javascript must be very cleanly written to give a chance to understand a part of what happens. This is the case for prototypejs, but is it true for every homemade framework?

  4. Back to top

    Re: Harder to debug

    Jun 25, 2008 6:44 AM by Francois Ward

    I can cause all of these issues in C# or Java too. Its a matter of conventions, idioms, and best practices. For example, the vast, vast majority of tutorials for prototypejs, ExtJS, ASP.NET AJAX, and more, will do it in an initialization event of some sort. As long as people stick to that, all is good.

  5. Back to top

    Re: Harder to debug

    Jun 25, 2008 7:22 AM by Bruno Vernay

    I agree : it must be really clear where in the code the behaviors are hooked up ! Otherwise, it will be a nightmare to debug and maintain. Besides, what about tooling, IDE and such ?

    If you modify the HTML, you may loose the link with the behaviors without notice.

    The CSS has "class" attribute that link to a specific CSS style the same way that an "onclick" link to a specific behavior. CSS is more about applying the same style to a whole bunch of pages.

    On the library side, it is a non-invasive way to add behavior to a site. Remove the javascript and the site will continue to run without errors.

    The loosely coupled triplet : Structure / Style / Behavior (HTML / CSS /Javascript) looks antagonist to the component or "widget" kind of development ?

  6. Back to top

    Clearer but slower

    Jun 25, 2008 7:30 AM by Luis Fernando Planella Gonzalez

    I work on a project that adopted Behaviour library. It is really nice, and look really temptating. The hello world works very nice... But... over the time, the pages started to get slower and slower... Some pages took 5-6 sec AFTER loading in order to respond in IE 6 (links, menus...) We had to hack it a lot, but it is really slower than using event handlers directly. And the slowness grows up with the page size. When want to have a page showing a table with hundreds of records, but we couldn't, since it took 30+ seconds in IE6 (damn IE). Luis

  7. Back to top

    XBL 2.0 meant to solve the issue...

    Jun 25, 2008 8:31 AM by Sergey Ilinsky

    Same code with XBL2 (note, there is no JS on HTML page at all):

    page.html:

    ...
    <style type="text/css">
      input#field {
        binding: url("behaviors.xml#click");
      }
    </script>
    ...
    <input id="field" />
    ...
    

    behaviors.xml:
    <?xml version="1.0"?>
    <xbl xmlns="http://www.w3.org/ns/xbl">
      <binding id="click">
        <handlers>
          <handler event="click">
            alert('hello');
          </handler>
        </handlers>
      </binding>
    </xbl>
    

    Specification: XML Binding Language (XBL) 2.0
    Implementation (Proof Of Concept): http://code.google.com/p/xbl/

  8. Back to top

    Re: XBL 2.0 meant to solve the issue...

    Jun 25, 2008 9:34 AM by Bruno Vernay

    You mean : CSS will link a HTML element to a XBL behavior that will call a Javascript function ...

    Hopefully you will have a powerful tool to link the HTML to CSS to XBL to JS !

    I agree that declarative style is the way to go, but I would wait for the tools to handle it.

Educational Content

Bindings, Platforms, and Innovation

This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.

Orchestrating Long Running Activities with JBoss / JBPM

This article explores the use of JBoss and jBPM to implement design solutions that effectively address the issue of orchestrating long running activities.

Neo4j - The Benefits of Graph Databases

This presentation covers the use of graph databases as an optimal solution for data that is difficult to fit in static tables, rapidly evolving data or data that has a lot of optional attributes.

Realistic about Risk: Software development with Real Options

This session introduces Real Options and shows how it can help in running your project. Real Options is a decision-making process that can be used to manage risk.

Communication Flexibility Using Bindings

This article discusses the use of bindings on services and references (including the instance of non-configured bindings) as the means to implement SCA communications in a Web and SOA environment.

Writing DSLs in Groovy

After a short introduction to DSLs, Scott Davis plays with the keyboard showing how to approach the creation of a DSL by typing working snippets of Groovy code that get executed.

Scaling Agile with C/ALM (Collaborative Application Lifecycle Management)

IBM Rational and InfoQ present, Scaling Agile with C/ALM, an eBook showing organizations how to become “finely tuned software delivery machines” by enabling team integration and scaling.

Concurrent Programming with Microsoft F#

Amanda Laucher presents a real life enterprise application written in F#. She shows actual code snippets, explaining design decisions and suggesting how to use some of the F# constructs.