20+ Irresistible jQuery Tips to Power Up Your JavaScript Skills

jQuery makes using JavaScript easy even for most designers because of it’s huge community and supply of really useful plugins. Using plugins is great for sure but knowing a bit more of what is going on behind the curtain can make you more powerful than you would expect. Digging into the coding details may not be that simple but with the good examples, tips and tricks in this article you should have a good chance.

Storing Data

Use data method and avoid storing data inside the DOM. Some developers have a habit of storing data in the HTML attributes like fx.:

$('selector').attr('alt', 'data being stored');
// later the data can be retrieved using:
$('selector').attr('alt');

HTML attributes is not meant to store data like that and the "alt" as a parameter name does not really make sense. The right alternative in most cases is using the data method in jQuery. It allows you to associate data with an element on the page.

$('selector').data('paramtername', 'data being stored');
// then later getting the data with
$('selector').data('paramtername');

This approach allows you to store data with meaningful names and it is more flexible as you can store as much data as you want on any element on the page. For more information about data() and removeData(), see here jQuery internals One classical use of this is saving the default value of a input field because you want to clear it on focus.

<form id="testform">
 <input type="text" class="clear" value="Always cleared" />
 <input type="text" class="clear once" value="Cleared only once" />
 <input type="text" value="Normal text" />
</form>
 
$(function() {
 //Go through every input field with clear class using each function
 //(NB! "clear once" is two classes clear and once)
 $('#testform input.clear').each(function(){
   //use the data function to save the data
   $(this).data( "txt", $.trim($(this).val()) );
 }).focus(function(){
   // On focus test for default saved value and if not the same clear it
   if ( $.trim($(this).val()) === $(this).data("txt") ) {
     $(this).val("");
   }
 }).blur(function(){
   // Use blur event to reset default value in field that have class clear
   // but ignore if class once is present
   if ( $.trim($(this).val()) === "" && !$(this).hasClass("once") ) {
     //Restore saved data
     $(this).val( $(this).data("txt") );
   }
 });
});

Demo here

Columns of equal height

This tip show you how to use two CSS columns, and make them having exactly the same height?

function equalHeight(columns) {
    tallest = 0;
    columns.each(function() {
        thisHeight = $(this).height();
        if(thisHeight > tallest) {
            tallest = thisHeight;
        }
    });
    columns.height(tallest);
}

/*
How it works:
$(document).ready(function() {
    equalHeight($(".box"));
});
*/

Test and improve you jQuery selector skills

This jQuery selector Lab is really cool and can be used free online and you can even download the lab and use it off-line. There’s a test page with most of the combination of html fields you can imagine and then a very long list of predefined selectors you can try. If that is not enough you can also type in your own selectors.

web-design-tutorial

Target blank links

Did you know that XHTML 1.0 Strict don’t allow "target=blank" attribute on links? Still it is quite useful to keep visitors on the site when they press an external link. A good solution to this problem should be using JQuery to make links opening in new windows. The rel="external" attribute is used to match the links that we want to open in a new window.

$('a[@rel$='external']').click(function(){
  this.target = "_blank";
});

/*
This is how it works:
<a href="http://www.tripwiremagazine.com/" rel="external">tripwiremagazine.com</a>
*/

Test if a jQuery collection contains any elements

If you need to test if a jQuery collection contains any elements you can simply try accessing the first element like this:

if($(selector)[0]){...}
// or you may use
if($(selector).length){...}

Let look at an example:

//ex. if you have this html on a page
<ul id="shopping_cart_items">
  <li><input class="in_stock" name="item" type="radio" value="Item-X" />Item X</li>
  <li><input class="unknown" name="item" type="radio" value="Item-Y" />Item Y</li>
  <li><input class="in_stock" name="item" type="radio" value="Item-Z" />Item Z</li>
</ul>
 
<pre lang="javascript" escaped="true">...
//The condition in this if statement will evaluate to true because we have two
// input fields that match the selector and the <statement> will be executed
if($('#shopping_cart_items input.in_stock')[0]){<statement>}

Use Callback to synchronize Effects

If you want to ensure that events occur one after the other you should use callbacks. Functions allow us to register a callback once the operation is over like this: slideDown( speed, [callback] ) ie. $('#sliding').slideDown('slow', function(){... Try try the example below here.

<style>
 div.button    { background:#cfd; margin:3px; width:50px;
   text-align:center; float:left; cursor:pointer;
   border:2px outset black; font-weight:bolder; }
 #sliding      { display:none; }
</style>
<script>
 
$(document).ready(function(){
// Use jQuery to change look of div once clicked and the event to
//start off the slide effect
 $("div.button").click(function () {
   //div.button will now look like a pushed down button
   $(this).css({ borderStyle:"inset", cursor:"wait" });
   //The hidden #sliding will now slide down and use callback to start the
   //slideup once it completes
   $('#sliding').slideDown('slow', function(){
     $('#sliding').slideUp('slow', function(){
       //once the slide up is over the callback change css for button back
       $('div.button').css({ borderStyle:"outset", cursor:"auto" });
     });
   });
 });
});
</script>

Use Events to control DOM Elements and Custom Objects

One of the most useful parts of jQuery is it’s ability to attach events to objects within a web page. When these events are triggered you can then use a custom function to do pretty much whatever you want with the event.There is a wide range of Events that are supported by jQuery and you will be able to create your own as well. Binding events to page elements doesn't get much easier and elegant here a few examples.

//Bind click event to a paragraph and write click coordinates to the page
$("p").bind("click", function(e){
  var str = "( " + e.pageX + ", " + e.pageY + " )";
  $("span").text("Click at coordinates: " + str);
});
 
//Binding multiple events is also simple and
$("p").bind("mouseenter mouseleave", function(e){
  //toggleClass adds the specified class if it is not present, removes
  //the specified class if it is present.
  $(this).toggleClass("mouse-over");
});

Not only can you bind events to DOM elements as simple as just illustrated. With jQuery you can actually bind a custom event to ANY object. Here is an example.

}
function shoppingCart() {
  // Do general shopping cart stuff here...
};
 
var myShoppingCart = new shoppingCart('personalShoppingCart');
jQuery(myShoppingCart).bind('addItem', function() {
  // Custom event handling for adding items to the shopping cart...
});
 
// Trigger custom event:
jQuery(myShoppingCart).trigger('addItem');
);

Learn to use Custom Selectors

On top of standard CSS selectors jQuery allow you to define custom selectors that makes your code even more simple.

$.expr[':'].mycustomselector= function(element, index, meta, stack){
    // element- is a DOM element
    // index - the current loop index in stack
    // meta - meta data about your selector
    // stack - stack of all elements to loop
 
    // Return true to include current element
    // Return false to explude current element
};
 
// Custom Selector usage:
$('.someClasses:test').doSomething();

Lets take a look at an example. This custom selector will return elements in the scope specified with attribute "rel":

$.expr[':'].withRel = function(element){
  var $this = $(element);
  //simply returning elements where rel is not empty
  return ($this.attr('rel') != '');
};
 
$(document).ready(function(){
//Using the custom selector is simple and the collection returned support chaining
// as illustrated here to apply some css to the returned elements
 $('a:withRel').css('background-color', 'green');
});
...
<ul>
  <li>
    <a href="#">without rel</a>
  </li>
  <li>
    <a rel="somerel" href="#">with rel</a>
  </li>
  <li>
    <a rel="" href="#">without rel</a>
  </li>
  <li>
    <a rel="nofollow" href="#">a link with rel</a>
  </li>
</ul>

Remove a word in a text

It is quite simple with jQuery to remove words in a element text? The following code can be easily modified to replace a word by another. In this case "wordtokill" is replaced by "wordtolive".

var element= $('#id');

element.html(element.html().replace(/wordtokill/ig, "wordtolive"));

Make entire Elements click-able

A lot of menus are created using simple <li> lists and css. It would be nice for the website usability if navigation was provided for the entire <li> and not just for the link text. jQuery makes this possible in a pretty simple way by taking the href (url) from the embedded link.

<ul>
  <li><a href="home">home</a></li>
  <li><a href="home">about</a></li>
  <li><a href="home">contact</a></li>
</ul>
...
//selector select all li within the ul and then we make them clickable.
$("ul li").click(function(){
  //get the url from href attribute and launch the url
  window.location=$(this).find("a").attr("href"); return false;
});

Preloading images

Generally it is a good idea to preload images if they are used in javescripts.

<pre>//Define function that preloads a defined list
//of images (arguments for the function).  
 
jQuery.preloadImages = function(){
  /Loop through the images
  for(var i = 0; i<arguments.length; i++){
    jQuery("<img>").attr("src", arguments[i]);
 
  }
}
// You can use usage the script this way:
$.preloadImages("images/logo.png", "images/logo-face.png", "images/mission.png");

Disable right-click contextual menu

As with other things we have been doing for years using javascript jQuery makes it simpler and more elegant. Of cause you can use this for much more. You may do something when the contextmenu event is fired.

<pre><pre>$(document).ready(function(){
    $(document).bind("contextmenu",function(e){
        return false;
    });
})

Make code simpler using group queries

A useful way to make the code simpler and easier to read is by grouping the queries for elements that need the same treatment.

// Don't do it like this as it takes up unnecessary space and takes time to write
$('div.close').click(doSomething);
$('button.close').click(doSomething);
$('input.close').click(doSomething);
 
// Simply use group queries in the selector if you have to
//apply same operation to them all
$('div.close, button.close, input.close')
    .click(doSomething);

Test your code well

jQuery comes with a unit test framework called QUnit. Writing tests is quite easy and allow you to confidently modify your code while ensuring that it still works as expected. Here is how it works:

<pre>//Separate tests into modules.
module("Module B");
 
test("some other test", function() {
  //Specify how many assertions are expected to run within a test.
  expect(2);
  //A comparison assertion, equivalent to JUnit's assertEquals.
  equals( true, false, "failing test" );
  equals( true, true, "passing test" );
});

web-design-tutorial

Minimize download time

Most browsers only download one script at the time and if you have several scripts being loaded on every page it can impact your download time. You can use Dean Edwards service "packer" to compress your scripts and make download faster. You need to maintain a development version and a runtime version as all you in-line comments will be lost. You will find it here.

jquery-tips

Another solution that take this to the extreme is interesting to take a look at. Basically it is a server based PHP script that combine javasctipt files and compress them in a easy to maintain approach. Take a look at and see if you can use the idea and some elements of the concept "Make your pages load faster by combining and compressing javascript and css files".

Logging to the Firebug console in jQuery

Firebug is one of my favourite Firefox extensions providing tons of tools in a very usable structure to aid you in HTML+CSS+JavaScript development. Obviously it is worth having just for it's excellent inspection feature allowing you to jump into the html and css and learn in a visual way what elements of the page is rendered by what code. As a jQuery and general Javascript developer Firefox also has good support for logging in your JavaScript code. The easiest way to write to the Firebug console looks like this:

console.log("hello world")

jquery-tips

You can pass as many arguments as you want and they will be joined together in a row, like

console.log(2,4,6,8,"foo",bar)

As a jQuery developer it even gets better using a tiny extension that Dominic Mitchell came up with to log any jQuery object to the console.

jQuery.fn.log = function (msg) {
    console.log("%s: %o", msg, this);
    return this;
};

With this extension you can simply call .log() on the object you are currently addressing fx.:

$('#some_div').find('li.source > input:checkbox')
    .log("sources to uncheck")
    .removeAttr("checked");

Use ID as Selector whenever possible

Selecting DOM elements using the class attribute is simpler than ever using jQuery. Even though it is simple it should be avoided whenever possible as as selecting using ID is much faster (In IE the class selector seams to loop through the entire DOM why generally it should be avoided). Selecting elements using IDs is fast because the browsers have the native getElementByID method that jQuery will use for IDs. Selecting classes still requires the DOM to be traversed behind the scene and if it is a large DOM and you make several lookups the performance impact can be significant. Let take a look at this simple html code:

<div id="main">
<form method="post" action="/">
  <h2>Selectors in jQuery</h2>
  ...
  ...
  <input class="button" id="main_button" type="submit" value="Submit" />
</form>
</div>
 
...
//Selecting the submit button using the class attribute
//like this is much slower than...
var main_button = $('#main .button');
 
//Selecting the submit button directly using the id like this
var main_button = $('#main_button');

Use Tags Before Classes

When you are selecting through tags jQuery will use the native browser JavaScript method, getElementsByTagName(). ID is still faster but this is still much faster than selecting with a class name.

<ul id="shopping_cart_items">
  <li><input class="in_stock" name="item" type="radio" value="Item-X" /> Item X</li>
  <li><input class="3-5_days" name="item" type="radio" value="Item-Y" /> Item Y</li>
  <li><input class="unknown" name="item" type="radio" value="Item-Z" /> Item Z</li>
</ul>

It is important to prefix a class with a tag name (here this is "input") and then it is important to descend from an ID to limit the scope of the selection:

var in_stock = $('#shopping_cart_items input.in_stock');

Cache jQuery Objects

Caching an object before working with it is essential for performance. You should neverdo like this:

<li>Description: <input type="text" name="description" value="" /></li>
...
$('#shopping_cart_items input.text').css('border', '3px dashed yellow');
$('#shopping_cart_items input.text').css('background-color', 'red');
$('#shopping_cart_items input.text').val("text updated");

In stead cache the object and work on it. The example below should really use chaining but it is just for illustration.

var input_text = $('#shopping_cart_items input.text');
input_text.css('border', '3px dashed yellow');
input_text.css('background-color', 'red');
input_text.val("text updated");
 
//same with chaining:
var input_text = $('#shopping_cart_items input.text');
input_text
 .css('border', '3px dashed yellow')
 .css('background-color', 'red')
 .val("text updated");

Bind certain jQuery functions to $(window).load event

Most jQuery code examples and tutorials instruct us to bind our jQuery code to the $(document).ready event. In many cases this is OK but since $(document).ready occurs during page render while objects are still downloading it may cause problems for some types of scripts. Functionality such as binding visual effects and animations, drag and drop, pre-fetching hidden images etc. could benefit from being bound to the $(window).load as it will ensure that all dependant elements are ready for use.

$(window).load(function(){
 // Put your jQuery functions that should only initialize after the page has loaded.
});

Use Chaining to limit selectors, make the code more simple and elegant

Because JavaScript supports chaining and because it works across line breaks you can structure your code like this. This example first removes a class on an element and then adds another to the same element.

$('#shopping_cart_items input.in_stock')
    .removeClass('in_stock')
    .addClass('3-5_days');

If needed it is really simple and useful as well to create a jQuery function that support chaining.

$.fn.makeNotInStock = function() {
    return $(this).removeClass('in_stock').addClass('3-5_days');
}
 
$('#shopping_cart_items input.in_stock').makeNotInStock().log();

Loading latest jQuery version from jquery.org

You can actually load the latest jQuery version using this code:

<script src="http://code.jquery.com/jquery-latest.js"></script>

This is handy if you quickly want to try out an idea for a script with the latest version. As you may know you can also load jQuery from ajax.googleapis.com as shown in #1 - Load the framework from Google Code here.

Load the framework from Google Code

Google have been hosting several JavaScript libraries for a while now on Google Code and you may want to load it from them instead of from your server.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
type="text/javascript"></script>

Use Cheat Sheets

Most people can't remember a lot of details and even though programmers tend to be better that the average the amount of information they need to have instant access too is devastating. Having a few cheat sheets printed out and placed next to the monitor is a good idea to speed up programming and to improve the code quality.

jQuery 1.4 API Cheat Sheet

jQuery 1.4 API Cheat Sheet

Related

-->