• Unobtrusive JavaScript

    Jun 2 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!

  • Comments

    1. Marco at 5:53am on June 2, 2006

    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 at 6:05am on June 2, 2006

    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 at 5:34pm on October 7, 2006

    shawn

    4. shawn at 10:20pm on May 25, 2007

    shawn

    5. shawn at 10:22pm on May 25, 2007

    shawn is posting this without javascript

    6. Jesse Skinner at 6:54am on May 26, 2007

    @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 at 11:23am on December 4, 2007

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

    8. nev at 11:29am on December 4, 2007

    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 at 7:07pm on December 5, 2007

    @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 at 2:49pm on December 6, 2007

    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 at 4:33pm on December 6, 2007

    @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 at 5:55pm on December 6, 2007

    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 at 3:31pm on December 9, 2007

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

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

    :)

    14. Chris at 8:24am on July 16, 2008

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

    Yhanx

    Chris

    15. Ghufron at 8:49pm on July 18, 2010

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

    Commenting is now closed. Come find me on Twitter.