the Future of the Web
  • Home
  • Hire Us
  • Articles
  • About
  • Contact
  • 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!

    Tags: javascript unobtrusive html bestpractices standards
    View 14 Comments | Add a comment
  • Comments

    1. Marco at 11: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 12:05pm 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 11:34pm on October 7, 2006

    shawn

    4. shawn at 4:20am on May 26, 2007

    shawn

    5. shawn at 4:22am on May 26, 2007

    shawn is posting this without javascript

    6. Jesse Skinner at 12:54pm 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 5:23pm on December 4, 2007

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

    8. nev at 5:29pm 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 1:07am on December 6, 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 8: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 10: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 11: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 9: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 2:24pm on July 16, 2008

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

    Yhanx

    Chris

    Add a Comment

    Note: HTML tags and entities will be converted so that they are displayed as you type them. This means if you type in <em>, people will see <em>, and if you type &lt;em&gt;, people will see &lt;em&gt;.

  • Request a Quote

  • Jesse Skinner

    Jesse Skinner
    • Hire Me
    • About Me
    • Email Me
    • RSS Feed RSS Icon
  • Recent Articles

    • Test Driven Development
    • Google is Hosting Ajax Libraries
    • Parse Accept-Language to detect a user's language
    • Twitter
    • Three years of The Future of the Web
    • Saving data to a file with PHP
    • Easy web scraping with PHP
    • See all the articles
    • IBM: Where and when to use Ajax
    • Code Igniter 1.6.0 Released
    • See All...
  • Categories

    • javascript (37)
    • links (20)
    • about (19)
    • web (14)
    • server (10)
    • html (10)
    • css (8)
    • carnival (7)
    • browsers (7)
    • design (4)
    • seo (4)
    • ads (4)
    • standards (4)
    • events (4)
    • work (4)
  • Older Articles

    • July 2008
    • June 2008
    • May 2008
    • April 2008
    • February 2008
    • January 2008
    • December 2007
    • November 2007
    • September 2007
    • August 2007
    • July 2007
    • June 2007
    • May 2007
    • April 2007
    • March 2007
    • February 2007
    • January 2007
    • December 2006
    • November 2006
    • October 2006
    • September 2006
    • August 2006
    • July 2006
    • June 2006
    • May 2006
    • April 2006
    • March 2006
    • February 2006
    • January 2006
    • December 2005
    • November 2005
    • October 2005
    • September 2005
    • August 2005
    • April 2005
    • See All...
Copyright © 2008 Jesse Skinner | CSS | XHTML | RSS | Help | Impressum | Cutie Quilts | Internet Blog Top Sites