<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.
Community comments
Good viewpoint
by Michael Minella,
Of course...
by Francois Ward,
Harder to debug
by Gabriel Kastenbaum,
Re: Harder to debug
by Francois Ward,
Re: Harder to debug
by Bruno Vernay,
Clearer but slower
by Luis Fernando Planella Gonzalez,
XBL 2.0 meant to solve the issue...
by Sergey Ilinsky,
Re: XBL 2.0 meant to solve the issue...
by Bruno Vernay,
Good viewpoint
by Michael Minella,
Your message is awaiting moderation. Thank you for participating in the discussion.
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,
Your message is awaiting moderation. Thank you for participating in the discussion.
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,
Your message is awaiting moderation. Thank you for participating in the discussion.
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,
Your message is awaiting moderation. Thank you for participating in the discussion.
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,
Your message is awaiting moderation. Thank you for participating in the discussion.
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,
Your message is awaiting moderation. Thank you for participating in the discussion.
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,
Your message is awaiting moderation. Thank you for participating in the discussion.
Same code with XBL2 (note, there is no JS on HTML page at all):
page.html:
behaviors.xml:
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,
Your message is awaiting moderation. Thank you for participating in the discussion.
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.