4/7/2014 - 2:45 PM

Unobtrusive Javascript

= Improving Your JavaScript =

==[Improving Your JavaScript] ==

=== Introduction ===
JavaScript has evolved over the years and there are things that can be done with JavaScript now 
that couldn't be done a few years ago. These tutorials present ways in which you can take existing 
JavaScript from a while ago and rework them to make better use of the newer features that are now 

=== The Best Place to Attach JavaScript ===

There are only two places that are even worth considering when it comes to attaching JavaScript to your 
page in the least obtrusive and most efficient way possible. They are to either place your script tag 
immediately before the </head> tag or immediately before the </body> tag of your page. 
In both cases you should be linking to an external script and ideally that script tag should be the 
only thing in the HTML that contains any JavaScript reference at all.

So how do we decide which of those two places to put the script tag? There are a few things we need to 
consider and the one that has the biggest impact is whether our web page is using HTML or is using XHTML. 
Note that which of these two you are using depends on the MIME type of the page with text/html being the 
MIME type for HTML and application/xml-xhtml being the MIME type for XHTML. Using an XHTML doctype with 
an HTML MIME type still means your page is HTML and so you should consider it as HTML for the following 

With the HTML DOM the elements in the DOM are available as soon as they are added to the web page and 
so as long as the element in the page you are referencing is before the call to the script you are trying 
to reference it from then the DOM reference from your JavaScript will work. This means that with your 
script tag immediately before the </body> tag that your JavaScript will be able to access all the 
elements in the page immediately without needing to test if the page or the DOM has finished loading.
It therefore doesn't matter whether your scripts placed at that point in the HTML page test for whether 
the page or the DOM are loaded before running since everything you want to access has already loaded 
whether those events have triggered or not.

The XHTML DOM works differently. Nothing in the XHTML DOM can be accessed until the DOM finishes loading. 
You therefore need to test for the DOM having loaded as the minimum requirement for being able to access 
anything in the page regardless of where you place the script tag.

Older browsers do not provide a way to test specifically if the DOM has loaded and so for those browsers 
you need to wait until the entire page has finished loading or alternatively set up a loop to test for 
when the appropriate element becomes accessible before accessing it if you place your script in the head 
of your page or are using XHTML. See[faster DOM access] 
for one way to set this up.

Another consideration for script placement is the way that web browsers load web pages. With all file 
types except for scripts old browsers could load files two at a time. For newer browsers the number of 
files they can load simultaneously has been increased to eight provided that none of them is a script. 
It is only in the very latest browsers where there is even a slight possibility that a script referenced 
from within your web page will be able to load at the same time as any other files referenced from the page.
The script will wait until all the files currently loading finish lading and will force all the other 
files that have yet to start loading to wait until the script finishes loading.

What this means is that if you place your script tag closer to the end of your page then you allow all 
the other files your page needs to load first and so the page will appear to load much faster. 
This provides another good reason for placing your script at the end of the body rather than in the head.

There is one way around the one script at a time limit for all browsers and that is because the limit only 
applies to scripts loaded directly from the HTML. If you dynamically add the script tags into the web page 
using JavaScript then those scripts added that way will start loading as soon as their tag has been added 
to the page without regard to what other files the web page may be loading at the same time.  Because 
those additional scripts are being loaded from JavaScript rather than from HTML they are not subject to 
the one at a time script limit that most browsers impose on HTML. 
See[adding JavaScript from JavaScript] for a short script 
that will make doing this really easy.

When you add the JavaScripts to your page from JavaScript itself at the bottom of the body then it doesn't 
really matter whether you add them to the head or the body of the web page since in either case you know 
that the DOM has already loaded prior to those scripts being added to the page.

In the case of XHTML and adding scripts it also doesn't matter where you add the JavaScripts but for the 
opposite reason. With XHTML you have to wait for the DOM to finish loading before you can run the script 
that adds the other scripts into your page.

Overall when you take all of these factors into account, the way in which to get your web page to appear 
to load as fast as possible by not being held up by scripts is to place the JavaScript at the end of the body. 
The way to make your script easier to write for HTML because you can do away with the need to test if the DOM 
is loaded is to place the script at the end of the body.

While placing your scripts in the head of the page may look neater because it reserves the body for what 
will actually appear in the web page, placing the script there will slow the loading of your page 
(which you can only minimise by reducing that script to one which dynamically adds the script tags after 
the page last loaded) and where the script itself will need to be more complex so as to ensure that the 
code doesn't try to run before the appropriate parts of the DOM are available.

=== Cross Browser AddEvent and RemoveEvent Listeners ===

This variant on adding and removing event listeners resolves some of the cross browser issues.

var addEvent, removeEvent;

if ( window.addEventListener ) {
    addEvent = function(obj, type, fn ) {
        obj.addEventListener(type, fn, false );
    removeEvent = function(obj, type, fn ) {
        obj.removeEventListener(type, fn, false );
else if (document.attachEvent) {
    addEvent = function(obj, type, fn ) {
        var eProp = type + fn;
        obj['e'+eProp] = fn;
        obj[eProp] = function(){obj['e'+eProp]( window.event );}
        obj.attachEvent( 'on'+type, obj[eProp] );
    removeEvent = function(obj, type, fn ) {
        var eProp = type + fn;
        obj.detachEvent( 'on'+type, obj[eProp] );
        obj[eProp] = null;
        obj["e"+eProp] = null;

Here's an example of the way you would write your call to actually use it.

var lnk = document.getElementById('ex');
addEvent(lnk, 'click', function(event) {

=== href="#" ===

A # by itself in the href attribute is not valid. Sites teaching you how to write HTML 
and JavaScript use it as a placeholder that should be replaced in live code with a 
real destination.

=== Self Documenting Code ===
You should not be using comments to describe what your code does, the code itself should show that.

=== New JavaScript Commands ===
Sometimes new commands are added to JavaScript. Older browsers may not be able to process these commands.

=== Getting Rid of document.write ===
The document.write statement was an essential part of early JavaScripts but is now completely unnecessary as anything that can be done with document.write can be done better using innerHTML.</p>

=== Accessibility and JavaScript ===
JavaScript should be coded in an unobtrusive fashion in order to make our web pages more accessible to those visitors who don't have it enabled.

<p><a href="/od/hintsandtips/a/nodots.htm" zt="18/1R4/Wa">Making Your JavaScript More Efficient</a><br>As JavaScript is an interpreted language there are minor changes to the way we write out code that will affect how quickly it will run.

<a href="/od/hintsandtips/a/noclash.htm" zt="18/1R4/Wa">Unobtrusive JavaScript - Avoiding Script Clashes</a><br>
There is more than one meaning when it comes to describing JavaScript as unobtrusive. 
Here we look at how to stop one JavaScript interfering with another JavaScript on the 
same page.

<a href="/library/blfastdom.htm" zt="18/1R4/Wa">Faster DOM Access</a><br>
Enable your Javascript code to interact with the DOM before the entire page finishes 
loading with this simple code change.

<a href="/od/hintsandtips/a/makeunobtrusive.htm" zt="18/1R4/Wa">Moving JavaScript out of the Web Page</a><br>How to separate the JavaScript in your web page from the HTML and put it in its own file.

<a href="/library/blnoscript.htm" zt="18/1R4/Wa">Getting Rid of Noscript</a><br>Here are a couple of simple examples to demonstrate how you can make your page more accessible, more semantically correct, as well as making the JavaScript completely unobtrusive simply by getting rid of the noscript tag.

<a href="/library/bleval.htm" zt="18/1R4/Wa">Alternatives to eval</a><br>The javascript command "eval" can be used to evaluate text as javascript. Doing so though opens up major security holes in your code as well as making the code way less efficient than it needs to be. There is (almost) never any need to use this function as for most uses there is an alternate coding that is cleaner and more efficient.

<p><a href="/od/hintsandtips/a/Table-Specific-Dom-Elements.htm" zt="18/1R4/Wa">Table Specific DOM Elements</a><br>There are two ways to access the elements within a table from JavaScript. I had always assumed that one of those ways was always faster than the other. It isn't in all browsers but by running a speed test I was able to come up with an actual comparison of the two methods so that I no longer need to assume that one is faster than the other...

<a href="/od/hintsandtips/a/Html-5-And-Noscript.htm" zt="18/1R4/Wa">HTML 5 And noscript</a><br>
HTML 5 proposes changing where the noscript tag can be used so as to reintroduce a use for it.

<a href="/library/blwrite.htm" zt="18/1R4/Wa">document.write</a><br>
It may be the easiest way to write something into your web page but document.write 
has a lot of limitations on how it can be used.

<a href="/od/hintsandtips/a/evolvingjavascript.htm" zt="18/1R4/Wa">Evolving JavaScript</a><br>
What JavaScript can and can't do has changed over time. What was best (or only) practice at 
one time may now be something to avoid.

<a href="/library/blunobtrusive.htm" zt="18/1R4/Wa">Unobtrusive JavaScript</a><br>
Your web page will work a lot better with the JavaScript completely removed from the HTML. 
Here's how to take all the JavaScript out of the body of your web page and still have it 
work just the same.

<a href="/od/hintsandtips/a/usability.htm" zt="18/1R4/Wa">Design for Usability</a><br>
Considerations for making a web page as accessible and user friendly as possible.

<a href="/od/hintsandtips/a/uevent.htm" zt="18/1R4/Wa">Making Events Unobtrusive</a><br>
Update old JavaScripts by converting them to make them unobtrusive. 
Here's step by step instructions on how to do it.