BT

AJAX developers continue migrating to unobtrusive JavaScript

by Matthew Bass on Jun 24, 2008 |
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.

Hello stranger!

You need to Register an InfoQ account or to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Good viewpoint 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:

www.michaelminella.com/javascript/unobtrusive-e...

Of course... 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.

Harder to debug by Gabriel Kastenbaum

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?

Re: Harder to debug 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.

Re: Harder to debug 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 ?

Clearer but slower 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

XBL 2.0 meant to solve the issue... 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): code.google.com/p/xbl/

Re: XBL 2.0 meant to solve the issue... 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.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

8 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2013 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT