Javascript tips

A collection of tips, code snippets and advice on all areas of Javascript development. Includes both core Javascript and jQuery, and is (hopefully) updated daily with something new. I’m hoping that eventually this page will become a great resource for anyone with a problem or error with their Javascript.

Thursday, September 29th, 2011

When you attach an event to a collection of elements using jQuery, the event will only affect elements which exist at that moment in time. For example:

// affects all matching elements which exist now
$('.alreadyExists').click(someFunction);
 
// this element will not have an onclick event
$(newElement).addClass('alreadyExists');

In this scenario, if you wanted to add the event to the new element, you would need another line of code adding the click event to the element.

If you find yourself in this situation, you should try using jQuerys “Live” event handler instead. It provides a way of ataching events to all current and future elements which match the given selector. For example:

// works for elements created later
$('.mightExist').live('click', someFunction);
 
// as soon as the class is added, the element also gets the onclick event handler
$(newElement).addClass('mightExist');
Tuesday, September 27th, 2011

The ternary operator is a nice alternative to more long winded if/else clauses that can really help the readability to your code. For example:

// instead of writing something like
if(b < 2) {
	a = c;
} else {
	a = d;
}
 
// you can use 
var a = (b < 2) ? c : d;

If that looks confusing, it might be more easily understood with the following:

variable = test ? value if true : value if false;

Essentially what happens is: the condition is tested, and one of two values is returned, depending on whether the condition was true or false.

Monday, September 26th, 2011

Did you know you can not only select existing DOM elements with jQuery’s all powerful $ function, but you can also create brand new ones? For example:

// core javascript
var myDiv = document.createElement('div');
// jQuery version
var myDiv = $('<div>');

You can also add all the usual attributes, and they will get parsed and created alongside the element itself, although it is also perfectly possible to just chain normal jQuery methods onto the element creation for the same results.

var myDiv = $('<div class="myClass">');
// is functionally identical to:
var myDiv = $('<div>').addClass('myClass');
Sunday, September 25th, 2011

If you ever have to deal with the possibility of visitors to your page having Javascript disabled (which you should, however unlikely it may seem), here is a dead simple method of detecting the lack of javascript and altering your page styles accordingly.

First you need to add a class to the pages body tag, something to signify a lack of javascript, so I use ‘nojs’.

<body class="nojs">

Then you need a bit of javascript to remove that class from the tag, here I am using jQuery, but you can use whatever you like, as long as it has the same effect. This needs to happen ASAP, so either stick a script tag immediately after the opening body tag, or use document ready.

$('body').removeClass('nojs');

Once those two bits are in place, you can start adding styles which cater for the lack of javascript simply by using the ‘.nojs’ selector. Any element which matches must by definition on a page in which the javascript to remove the class has not run, and you can safely assume there is no javascript at all (or at least you can if your class removal code is solid, which is why I would recommend jQuery).

.nojs .myclass { display: none; }
.nojs .myotherclass { top: 20px; }

The two examples above show the sort of thing you can use this for, such as to display a element which would otherwise be revealed by javascript, or to move something into view which would normally be animated by javascript.

Saturday, September 24th, 2011

Everyone who has used jQuery for longer than a few minutes is probably aware of the document ready function:

$(document).ready(function(){
    // do something
});

By wrapping your code up like that you guarantee that any html elements you need to reference have actually been created and are ready for manipulation. Simple enough, but there’s actually an even simpler way of doing the same thing:

$(function(){
    // this works exactly the same
});

Handy eh? Also, because all you’re really doing is passing in a function, it doesn’t have to be anonymous like in the above examples. Try passing in a reference to an existing function:

function startup() {
    // do stuff
}
$(startup);

The startup function will then be called on document ready, but could also be called separately if needed.

Friday, September 23rd, 2011

Instead of doing something this:

// normal way to loop through an array
for(i = 0; i < myArray.length; i++) {
    // do something
}

Try this slightly modified syntax:

// declaring variables properly helps keep the global scope clean
// but more importantly, assigning the length to a variable and testing that instead means
// that the array length is only calculated at the start, not once per iteration
for(var i = 0, len = array.length; i < len; i++) {
    // do something slightly faster
}

It’s a small change, but if you have a lot of loops, or work with very large arrays, it can soon add up.

Thursday, September 22nd, 2011

If you ever have multiple scripts on a page which use the $ variable (such as prototype), you can use the jQuery’s handy noConflict method to tell it to give up control of $, allowing the other library to use it instead. For example:

// will not work because $ is conflicting
$('.myClass').show();
 
// tell jQuery to play nice
jQuery.noConflict();
 
// will (probably) not work because $ is not longer a reference to jQuery
$('.myClass').show();
 
// will work instead
jQuery('.myClass').show();

Interestingly, the noConflict method returns a reference to the jQuery object, so there is nothing stopping you deciding on your own variable for future jQuery calls, like so:

// assign the result to a variable
var jq = jQuery.noConflict();
 
// jq is now functionally identical to jQuery, so this works
jq('.myClass').show();

Not earth shatteringly useful I admit, but seeing as part of the attraction of jQuery is the brevity of it’s code, having to use “jQuery” everywhere can be quite annoying, which this nicely sidesteps.