Coding with Jesse

Unobtrusive JavaScript

June 2nd, 2006

You might have heard of unobtrusive JavaScript, but what the hell is it? Well, it's the separation of all your JavaScript from your HTML. That means putting all your JavaScript either in a <script> block, or even better, in an external file.

Why bother? Yes, sometimes it's easier to put JavaScript into onclick or onload attributes. But it's better to separate your content (HTML) from your presentation (CSS) from your behaviour (JavaScript). It keeps your HTML clean. It also makes things easier to maintain.

It's not just about the physical separation of JavaScript from HTML. It's the absolute separation. Your HTML should work without JavaScript. For example, if you have an empty <body> tag, and then attach use Ajax to pull content from the server and stick it into the body, that sucks. If somebody comes to your site without JavaScript (ie. the Google spider), they will get an empty page.

It's important that your whole site works without JavaScript. This way, your content can be used by people without JavaScript. Google's spider doesn't support JavaScript (to my knowledge). So, if you want your content to be indexed, make sure your HTML content can stand alone without JavaScript.

Unobtrusive JavaScript means adding JavaScript functionality on top of an already functional HTML site. This improves things for those with JavaScript without taking anything away from those without. Let's look at some simple examples.

The onload attribute on the <body> tag is popular. Instead of doing this:

<script>
function myLoadScript() {
   // do fancy stuff
}
</script>

<body onload="myLoadScript()">

you can just do this:

<script>
window.onload = function () {
   // do fancy stuff
}
</script>

<body>

There's no difference in functionality, but it does let you put your script in another file and have less stuff in the HTML. This way, you can change or remove your onload function without changing the HTML.

Here's another example. Let's say you have some JavaScript in a link to launch a popup window:

<script>
function showPopup() {
    window.open('myPopupPage.html',null,"width=600,height=400,toolbar=no");
}
</script>

<a href="javascript:showPopup()">I love popups!</a>

If somebody doesn't have JavaScript, this won't work. That sucks. You can do this instead:

<script>
function showPopup() {
    window.open('myPopupPage.html',null,"width=600,height=400,toolbar=no");
    return false;
}

window.onload = function () {
   document.getElementById('popupLink').onclick = showPopup;
}
</script>

<a id="popupLink" href="myPopupPage.html" target="_blank">I love popups!</a>

If somebody doesn't have JavaScript, they'll still get the normal link popup from the HTML alone. You won't be able to customize the size, toolbars, etc. but at least it will still partially work.

Notice that the showPopup() function now returns false. This will stop the page from doing what it normally does when you click the link. In other words, you'll only get the JavaScript popup, not two popups.

This technique can be applied to more complex JavaScript including Ajax techniques. If you have a form that is submitted in the background, and uses JavaScript to redraw the page without refreshing, great. Just add this functionality using JavaScript alone. Make sure that without JavaScript, the form just submits and the page refreshes the old-fashioned Web 1.0 way.

I will quickly mention something to silence those who are screaming at their monitors. document.getElementById doesn't work in every browser (like Internet Explorer 4 or Netscape 4), so you may want to use object detection to make sure it's supported. My policy is that if someone is using an older browser, they get the same thing as if they had JavaScript turned off.

I hope these techniques will help you to create wonderful, clean, sexy and modern unobtrusive JavaScript. Have fun!


Interested in web development? Subscribe to my newsletter!

Comments

1 . Marco on June 2nd, 2006

Marco

You say:

"It's important that your whole site works without JavaScript. This way, your content can be used by people without JavaScript. Google's spider doesn't support JavaScript (to my knowledge). So, if you want your content to be indexed, make sure your HTML content can stand alone without JavaScript."

This doesn't really sound all that convincing. You don't say WHY the site should be usable for people without javascript. This (IMHO) only applies to some cases (like pure information sites) but definitely not to all (e.g. an AJAX chat app on a site).

The Google thing: As long as the part that matters for indexing is readable by the bot you'll be perfectly fine.

Like I said on Rogers' site: I'm all in favor of unobtrusive script in terms of separation of JS from the markup but I just don't see why ALL websites should work 100% without JS.

2 . Jesse Skinner on June 2nd, 2006

Jesse Skinner

I think it's okay for JavaScript to be required for certain things. For example, I require JavaScript to post comments to cut down on comment spam. I see posting comments as extra functionality, not some fundamental right. This would be even more true for real applications where JavaScript is unavoidably required.

However, I've seen web sites that required JavaScript for some fancy Ajax techniques for no good reason. This was cutting out both spiders and others just to avoid reloading the page. This is inappropriate.

Beyond this, unobtrusive JavaScript is also just a best practice nice-to-have that cleans up the HTML and makes things easier to work with. As long as the content is available, the rest is mostly code aesthetics.

3 . shawn on October 7th, 2006

shawn

shawn

4 . shawn on May 25th, 2007

shawn

shawn

5 . shawn on May 25th, 2007

shawn

shawn is posting this without javascript

6 . Jesse Skinner on May 26th, 2007

Jesse Skinner

@shawn - Yes, I've updated my blog system so those without JavaScript can still post, by using a CAPTCHA that is filled out automatically using JavaScript. Best of both worlds.

7 . nev on December 4th, 2007

nev

Does this sort of js popup get blocked by browser's "popup blockers"?

8 . nev on December 4th, 2007

nev

Also - you can't use this on a page with many dynamically created links, as there's only one link in the showPopup() script.

9 . Jesse Skinner on December 5th, 2007

Jesse Skinner

@nev - you could modify the script to look at the href attribute like this:

function showPopup() {
window.open(this.href, null,"width=600,height=400,toolbar=no");
return false;
}

then the function will work when attached to any link.

10 . nev on December 6th, 2007

nev

If you try to use a query string, like:

<a id="popupLink" href="popup.php?pageid=1" target="_blank">pop-up page</a>

... the link won't pass it onto the receiving pop-up page. You have to put the query string into the js code for that to work, like this:

window.open('popup.php?pageid=1',null,"width=600,height=400,toolbar=no");

...which is no good for multiple links.

And Jesse - if I change:

window.open('myPopupPage.html',null,"width=600,height=400,toolbar=no");

to:

window.open(this.href, null,"width=600,height=400,toolbar=no");

..as in your example, this will still only work for a link that has the id="popupLink", and you can only have one of those per page.

11 . Jesse Skinner on December 6th, 2007

Jesse Skinner

@nev - have a look here for a solution which adds a similar function to all links with a particular class name:

http://www.thefutureoftheweb.com/blog/target-blank-xhtml11

You could also alter it to look for target="_blank" instead of a class name.

12 . nev on December 6th, 2007

nev

Well really I was looking for a "dual" method to open a new window - that is, one which (a) uses js if js is available to the browser, so that the new window can be the size I want it, etc., but which (b) also uses the target method as a fallback for browsers without js. And I wanted to use this on a dynamic page with lots of links. Molto problemo.

13 . nev on December 9th, 2007

nev

Well - I found it! Explained in all its glory here:

http://www.accessify.com/features/tutorials/the-perfect-popup/archive/

:)

14 . Chris on July 16th, 2008

Chris

Any chance to get this scripts working for 2 or more popup windows from one page?

Yhanx

Chris

15 . Ghufron on July 18th, 2010

Ghufron

Thank you, it works fine on my site...

Comments are closed, but I'd still love to hear your thoughts.