Unobtrusive JavaScript

I think the biggest thing that bugs me is when I see an HTML element with “onclick” or “onblur” as an attribute; that’s such lazy code, and it leads to difficult maintenance of web sites. But how else are you supposed to do it? Well, that’s what I’m going to explain to you in the coming series on Unobtrusive JavaScript.

To give a little history, when HTML first was emerging, the structure of the code was very tied in to the design of the web page. Table Layouts are a great example of bad coding practices: the content of the HTML was used to create the style of the website. As a result, CSS arose to keep the presentation layer apart from the structure layer. With that in mind, let’s look at JavaScript; it’s what’s considered the behavior layer of web design. Since that is another layer entirely, we should apply the same principle of separating it from the other two layers. Thus, Unobtrusive JavaScript was conceived.

The idea behind this practice is that separating the code from the HTML will lead to easier maintenance of websites, as the code is consolidated in one spot, and the HTML in another. So let’s get to some examples:

document.addEventListener("DOMContentLoaded", (function(event){

  var fName = document.getElementById("fName"); // <input type='text' id='fName' /> 

  // When the fName input's value changes, alert the 
  // user of this occurance. Not very useful, but it's 
  // equivalent in obtrusive JavaScript looks like this:

  // <input type='text' id='fName' onchange="alert(this.id + \" Has Been Changed!\");" />

  // Now you tell me, which is easier to maintain??

  fName.addEventListener("change", (function(e){  
    alert(this.id + " Has Been Changed!");
  }), false);

}), false);

But of course, life is never that easy, is it? Microsoft had to come up with their own method of implementing the Event Listeners, and thus “attachEvent()” was born. Since there are two ways we need to implement events for the two major browsers, it makes sense to create a function that figures out which method should be used, so if the browser is W3C DOM, it will call addEventListener, and if it’s Microsoft DOM, it will call attachEvent.

var addEvt = function( el, evt, callback ){
  if( el.addEventListener ){ // If W3C, use addEventListener
    el.addEventListener( evt, callback, false );
  } else if( el.attachEvent ){ // Else if Microsoft, use attachEvent
    el.attachEvent( "on"+evt, callback );
  } else{
    el["on"+evt] = callback; // Ugly hack for neither type. Arguably intrusive

    if( el["on"+evt] == null ){
      alert("You Need a Better Browser. Get Google Chrome.");
    }
  }
}

That provides an abstracted API for adding event handlers to elements. In other words, one function for adding handlers will now work for three different methods of implementing event handlers! We’ll stop here for this post, so stay tuned for the next post, showing how to use this in an application!

Thanks!
Kyle

Leave a Comment

Scroll to Top