Unobtrusive JavaScript

Unobtrusive JavaScript is an approach to JavaScript programming intended to facilitate progressive enhancement, separation of functionality from content/presentation, and overall best practice.

The basic concept behind unobtrusive JavaScript (also known as "unobtrusive DOM scripting") is to provide a best practice approach to JavaScript programming that maintains usability and accessibility, and degrades gracefully. Code maintainability from a programming perspective can also be considered a goal of unobtrusive JavaScript.

Basic Example of Unobtrusive JavaScript

Here's a basic example to demonstrate the concept.

If you enter your name into the following input field, your name will appear under the input field. It will update with each letter you type. You don't need to click any buttons to make this happen. It just works.

If you remove the JavaScript from that example, it will still work, but in a slightly different way.

Here it is with the JavaScript removed:

When you remove the JavaScript, a button appears. You need to click the button before your name appears below the input field.

In this case, we provide enhanced functionality for users with JavaScript enabled, and basic functionality for non-JavaScript users. The end result is the same — users enter their name and the web page displays it back to them.

Of course, most web applications are much more complex than this, but if they use unobtrusive JavaScript, their core functionality will still work for non-JavaScript users — even if it requires a few extra clicks.

The important thing is, the user won't know any different. They won't get any nasty error messages telling them to upgrade their browser or anything like that. Non-JavaScript users will simply use the website as it is intended for them. They won't know that JavaScript users get an enhanced experienced.

One other observation of the above example is that, the HTML contains no JavaScript — not even an event handler. Removing the JavaScript was a simple matter of deleting the script tag. We didn't have to go through the HTML code and remove event handlers, function calls, etc.

Unobtrusive JavaScript Principles

While there's no formal definition for unobtrusive JavaScript, the approach generally adheres to the following core principles.

Usability

Unobtrusive JavaScript runs without drawing attention to itself. The script is a useful addtion to the website, but it is so integrated, and works so well that the user simply uses the website (and its scripts) without thinking about it.

Graceful Degradation or Progressive Enhancement

Graceful degradation of JavaScript means that the script doesn't draw attention to itself when it fails.

Different browsers support different features. So when you write some JavaScript, there's a possibility that not all browsers will support some of the features you're using in your script. Rather than display an error message when you try to run the unsupported script, your script detects whether the browser supports your objects before it tries to run the script. It can then deal with it in another way, perhaps by running a different script that is supported, or by reverting to an HTML/server-side scripting solution.

When developing, graceful degradation is an approach where you focus on providing functionality for the "best case scenario" (e.g. for browsers that support all your functionality), then work out ways of making it work well in other cases (e.g. browsers that don't support all of the enhanced functionality).

Progressive enhancement on the other hand, works in the reverse order. You concentrate on providing functionality that works in all situations, then provide "extra" functionality that more advanced browsers can take advantage of.

Accessibility

The benefits of including JavaScript on a website can be great. But these benefits will only be available for users with JavaScript enabled. Also, some users with disabilities might have trouble with JavaScript.

In other words, not all users can actually use your JavaScript.

When you use unobtrusive JavaScript, the website will still work for those "non-JavaScript" users. This usually means that your HTML code (often in conjunction with a server-side script) provides the same (or similar) functionality that would've been achieved with the JavaScript. It might not work exactly like the JavaScript version, but at least it doesn't prevent those users from completing their task.

You might say, "well why bother even doing it in JavaScript then?".

Good point. Here's one of the main reasons for using JavaScript in a web page.

Generally speaking, JavaScript can provide a more interactive experience for the user. And because it runs on the client side, it can do things a lot quicker than if we'd had to send a request to a server-side script.

The previous example demonstrates this. We were able to provide an interactive input field for the user, but we also provided a scaled down solution for non-JavaScript users.

Separation

When using unobtrusive JavaScript, all scripts and their event handlers are kept away from the HTML.

Unobtrusive JavaScript is maintained separately to the HTML file. All JavaScript resides in its own file and the HTML file simply links to this file. Also, instead of using inline event handlers embedded within HTML tags (such as onclick=""), unobtrusive JavaScript uses other techniques to detect events.

While the end user doesn't care whether JavaScript is inline or not, developers who work on the site will typically find the code easier to maintain this way. This is considered "unobtrusive" because it hides the JavaScript from those developers who don't need to look at the JavaScript. Developers who need to look at the JavaScript can simply open the relevant file.

Let's look at the previous example again, but this time we'll take a closer look at the code.

The HTML:

The Javascript (file here):

This code uses a technique that allows us to keep the JavaScript completely separate from the HTML. All JavaScript resides in an external file.

If we didn't use unobtrusive JavaScript, we might insert an onclick attribute into the input tag in order to trigger a function. So it might look something like this:

However, this doesn't follow the unobtrusive JavaScript principle of keeping the JavaScript away from the content and presentation.

Therefore, we use this (inside the .js file) instead:

This goes with the rest of the JavaScript and therefore, it can easily reside in a separate .js file. This means there's no need to put onclick into any form elements.

Loading the DOM

Another thing about this example is that all JavaScript is wrapped inside this:

This code allows us to wait for the document object model (DOM) to load before running the rest of the code. We do this to ensure that we can make reference to any object on the page — even if it comes later on in the code. If we didn't do this, we wouldn't be able to call the HTML elements further down the page.

We then use some trickery to hide the button from JavaScript users:

They won't be needing it. This button is only for non-JavaScript users. If they don't have JavaScript enabled, then JavaScript won't be able to hide the button, which is exactly what we want.

This is a basic example, and there are other things you could do to make your JavaScript unobtrusive. For example, rather than hide the button for all JavaScript users, you could go a step further and check whether the browser supports the specific objects that you're going to use in your script. So the button could hide/display elements based on that test.