15 Powerful jQuery Tips and Tricks for Developers

15 Powerful jQuery Tips and Tricks for Developers

In this article we will take a look at 15 jQuery techniques which will be useful for your effective use of the library. We will start with a few tips about performance and continue with short introductions to some of the library’s more obscure features.

1) Use the Latest Version of jQuery

With all the innovation taking place in the jQuery project, one of the easiest ways to improve the performance of your web site is to simply use the latest version of jQuery. Every release of the library introduces optimizations and bug fixes, and most of the time upgrading involves only changing a script tag.

You can even include jQuery directly from Google’s servers, which provide free CDN hosting for a number of JavaScript libraries.

<!-- Include a specific version of jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>

<!-- Include the latest version in the 1.6 branch -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>

The latter example will include the latest 1.6.x version automatically as it becomes available, but as pointed out on css-tricks, it is cached only for an hour, so you better not use it in production environments.

2) Keep Selectors Simple

Up until recently, retrieving DOM elements with jQuery was a finely choreographed combination of parsing selector strings, JavaScript loops and inbuilt APIs like getElementById(), getElementsByTagName() and getElementsByClassName(). But now, all major browsers support querySelectorAll(), which understands CSS query selectors and brings a significant performance gain.

However, you should still try to optimize the way you retrieve elements. Not to mention that a lot of users still use older browsers that force jQuery into traversing the DOM tree, which is slow.

$('li[data-selected="true"] a')	// Fancy, but slow
$('li.selected a')	// Better
$('#elem')	// Best

Selecting by id is the fastest. If you need to select by class name, prefix it with a tag – $('li.selected'). These optimizations mainly affect older browsers and mobile devices.

Accessing the DOM will always be the slowest part of every JavaScript application, so minimizing it is beneficial. One of the ways to do this, is to cache the results that jQuery gives you. The variable you choose will hold a jQuery object, which you can access later in your script.

var buttons = $('#navigation a.button');

// Some prefer prefixing their jQuery variables with $:
var $buttons = $('#navigation a.button');

Another thing worth noting, is that jQuery gives you a large number of additional selectors for convenience, such as :visible, :hidden, :animated and more, which are not valid CSS3 selectors. The result is that if you use them the library cannot utilize querySelectorAll(). To remedy the situation, you can first select the elements you want to work with, and later filter them, like this:

$('a.button:animated');	// Does not use querySelectorAll()
$('a.button').filter(':animated');	// Uses it

The results of the above are the same, with the exception that the second example is faster.

3) jQuery Objects as Arrays

The result of running a selector is a jQuery object. However, the library makes it appear as if you are working with an array by defining index elements and a length.

// Selecting all the navigation buttons:
var buttons = $('#navigation a.button');

// We can loop though the collection:
for(var i=0;i<buttons.length;i++){
	console.log(buttons[i]);	// A DOM element, not a jQuery object
}

// We can even slice it:
var firstFour = buttons.slice(0,4);

If performance is what you are after, using a simple for (or a while) loop instead of $.each(), can make your code several times faster.

Checking the length is also the only way to determine whether your collection contains any elements.

if(buttons){	// This is always true
	// Do something
}

if(buttons.length){ // True only if buttons contains elements
	// Do something
}

4) The Selector Property

jQuery provides a property which contains the selector that was used to start the chain.

$('#container li:first-child').selector    // #container li:first-child
$('#container li').filter(':first-child').selector    // #container li.filter(:first-child)

Although the examples above target the same element, the selectors are quite different. The second one is actually invalid – you can’t use it as the basis of a new jQuery object. It only shows that the filter method was used to narrow down the collection.

5) Create an Empty jQuery Object

Creating a new jQuery object can bring significant overhead. Sometimes, you might need to create an empty object, and fill it in with the add() method later.

var container = $([]);
container.add(another_element);

This is also the basis for the quickEach() method that you can use as a faster alternative to the default each().

6) Select a Random Element

As I mentioned above, jQuery adds its own selection filters. As with everything else in the library, you can also create your own. To do this simply add a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of his code below:

(function($){
    var random = 0;

    $.expr[':'].random = function(a, i, m, r) {
        if (i == 0) {
            random = Math.floor(Math.random() * r.length);
        }
        return i == random;
    };

})(jQuery);

// This is how you use it:
$('li:random').addClass('glow');

7) Use CSS Hooks

The CSS hooks API was introduced to give developers the ability to get and set particular CSS values. Using it, you can hide browser specific implementations and expose a unified interface for accessing particular properties.

$.cssHooks['borderRadius'] = {
        get: function(elem, computed, extra){
            // Depending on the browser, read the value of
            // -moz-border-radius, -webkit-border-radius or border-radius
        },
        set: function(elem, value){
            // Set the appropriate CSS3 property
        }
};

// Use it without worrying which property the browser actually understands:
$('#rect').css('borderRadius',5);

What is even better, is that people have already built a rich library of supported CSS hooks that you can use for free in your next project.

8) Use Custom Easing Functions

You have probably heard of the jQuery easing plugin by now – it allows you to add effects to your animations. The only shortcoming is that this is another JavaScript file your visitors have to load. Luckily enough, you can simply copy the effect you need from the plugin file, and add it to the jQuery.easing object:

$.easing.easeInOutQuad = function (x, t, b, c, d) {
	if ((t/=d/2) < 1) return c/2*t*t + b;
	return -c/2 * ((--t)*(t-2) - 1) + b;
};

// To use it:
$('#elem').animate({width:200},'slow','easeInOutQuad');

9) The $.proxy()

One of the drawbacks to using callback functions in jQuery has always been that when they are executed by a method of the library, the context is set to a different element. For example, if you have this markup:

<div id="panel" style="display:none">
	<button>Close</button>
</div>

And you try to execute this code:

$('#panel').fadeIn(function(){
	// this points to #panel
	$('#panel button').click(function(){
		// this points to the button
		$(this).fadeOut();
	});
});

You will run into a problem – the button will disappear, not the panel. With $.proxy, you can write it like this:

$('#panel').fadeIn(function(){
	// Using $.proxy to bind this:

	$('#panel button').click($.proxy(function(){
		// this points to #panel
		$(this).fadeOut();
	},this));
});

Which will do what you expect. The $.proxy function takes two arguments – your original function, and a context. It returns a new function in which the value of this is always fixed to the context. You can read more about $.proxy in the docs.

10) Determine the Weight of Your Page

A simple fact: the more content your page has, the more time it takes your browser to render it. You can get a quick count of the number of DOM elements on your page by running this in your console:

console.log( $('*').length );

The smaller the number, the faster the website is rendered. You can optimize it by removing redundant markup and unnecessary wrapping elements.

11) Turn your Code into a jQuery Plugin

If you invest some time in writing a piece of jQuery code, consider turning it into a plugin. This promotes code reuse, limits dependencies and helps you organize your project’s code base. Most of the tutorials on Tutorialzine are organized as plugins, so that it is easy for people to simply drop them in their sites and use them.

Creating a jQuery plugin couldn’t be easier:

(function($){
	$.fn.yourPluginName = function(){
		// Your code goes here
		return this;
	};
})(jQuery);

Read a detailed tutorial on turning jQuery code into a plugin.

12) Set Global AJAX Defaults

When triggering AJAX requests in your application, you often need to display some kind of indication that a request is in progress. This can be done by displaying a loading animation, or using a dark overlay. Managing this indicator in every single $.get or $.post call can quickly become tedious.

The best solution is to set global AJAX defaults using one of jQuery’s methods.

// ajaxSetup is useful for setting general defaults:
$.ajaxSetup({
	url			: '/ajax/',
	dataType	: 'json'
});

$.ajaxStart(function(){
	showIndicator();
	disableButtons();
});

$.ajaxComplete(function(){
	hideIndicator();
	enableButtons();
});

/*
	// Additional methods you can use:
	$.ajaxStop();
	$.ajaxError();
	$.ajaxSuccess();
	$.ajaxSend();
*/

Read the docs about jQuery’s AJAX functionality.

13) Use delay() for Animations

Chaining animation effects is a powerful tool in every jQuery developer’s toolbox. One of the more overlooked features is that you can introduce delays between animations.

// This is wrong:
$('#elem').animate({width:200},function(){
	setTimeout(function(){
		$('#elem').animate({marginTop:100});
	},2000);
});

// Do it like this:
$('#elem').animate({width:200}).delay(2000).animate({marginTop:100});

To appreciate how much time jQuery’s animation() save us, just imagine if you had to manage everything yourself: you would need to set timeouts, parse property values, keep track of the animation progress, cancel when appropriate and update numerous variables on every step.

Read the docs about jQuery animations.

14) Make Use of  HTML5 Data Attributes

HTML5 data attributes are a simple means to embed data in a webpage. It is useful for exchanging data between the server and the front end, something that used to require outputting <script> blocks or hidden markup.

With the recent updates to the jQuery data() method, HTML5 data attributes are pulled automatically and are available as entries, as you can see from the example below:

<div id="d1" data-role="page" data-last-value="43" data-hidden="true"
	data-options='{"name":"John"}'>
</div>

To access the data attributes of this div, you would use code like the one below:

$("#d1").data("role");			// "page"
$("#d1").data("lastValue");		// 43
$("#d1").data("hidden");		// true;
$("#d1").data("options").name;	// "John";

Read more about data() in the jQuery docs.

15) Local Storage and jQuery

Local storage is a dead simple API for storing information on the client side. Simply add your data as a property of the global localStorage object:

localStorage.someData = "This is going to be saved across page refreshes and browser restarts";

The bad news is that it is not supported in older browsers. This is where you can use one of the many jQuery plugins that provide different fallbacks if localStorage is not available, which makes client-side storage work almost everywhere.

Here is an example using the $.jStorage jQuery plugin:

// Check if "key" exists in the storage
var value = $.jStorage.get("key");
if(!value){
	// if not - load the data from the server
 	value = load_data_from_server();
 	// and save it
	$.jStorage.set("key",value);
}

// Use value

To Wrap it Up

The techniques presented here will give you a head start in effectively using the jQuery library. If you want something to be added to this list, or if you have any suggestions, use the comment section below.

by Martin Angelov

Martin is a web developer with an eye for design from Bulgaria. He founded Tutorialzine in 2009 and publishes new tutorials weekly.

Articles

39 Comments

  1. Thanks Martin. Great write up as usual. :)

  2. Catalin says:

    Martin, thanks for sharing these good tips!

    Regarding Jquery hosted versions, I usually use the Jquery CDN: http://code.jquery.com/jquery-latest.min.js.

    1. Martin Angelov says:

      The Google CDN does not provide a way to link to the absolutely latest version (you can only link to the latest major version, 1 being the current one), but your suggestion solves that problem.

      There is one drawback to using the latest version, however - there might be breaking changes, as in the case with .attr() in jQuery 1.6, so jquery-latest should probably be used only in development.

  3. Fantastic article. Thank you for the write up; it has helped me to understand a lot more about jQuery.

  4. Ryan Keefer says:

    Great writeup and refresher on some great, albeit easy ways to optimize your usage of jQuery. Thanks for the article.

  5. Imran says:

    Really helpful article...

  6. Andon says:

    Awesome article! Thanks!

  7. JP says:

    Nice article!

    Could you provide more performance tweaks & tips for jQuery powered applications in the future?

  8. rswrc says:

    On what browsers local storage is supported and how to test if it is supported?

    1. Martin Angelov says:

      Nearly all currently used browsers support localStorage. The exception being IE before version 8.

      Testing for localStorage support is quite easy:

      function supportsLocalStorage(){
          return 'localStorage' in window;
      }
      
      if(supportsLocalStorage()){
          // Use localStorage
      }
      

      However the $.jStorage plugin handles this check itself.

  9. Nice collection! Thanks!

  10. rajeev verma says:

    I have recently shifted from YUI to jquery and your tutorial was of great help.Thanks.

  11. Flint says:

    Nice article! Keep it up.

  12. Awesome post dude!
    Keep it up...

  13. Thanks a lot for such a great article on jQuery !
    A great addition for the tips & tricks you already mentioned would be:
    Preventing jQuery animations queue bildup (example: http://www.learningjquery.com/2009/01/quick-tip-prevent-animation-queue-buildup) !

  14. rmaksim says:

    13) Use delay() for Animations
    wrong syntax setTimeout(2000,function(){...

    Syntax:
    var t = setTimeout("javascript statement", milliseconds);

    1. Martin Angelov says:

      Thank you for catching that. Fixed.

  15. Great and very handy tips. i love the Local storage bit. many thanks.

  16. Patrick McLaughlin says:

    Great article! Thanks for writing and sharing.

  17. Guillaume says:

    Thanks for the tips ! Didn't how about $.proxy ! Huge help !

  18. Fernando Lee says:

    Hey this article is top notch great work

  19. Marco says:

    Nice tips but about the use of the lastest version I think it is not always the best option. The last version probably is not cached by most of browsers and it means the browser has to download the library. If you use a previous version the chance the browser has already downloaded the library from another website is higher.
    So do you really need the latest version considering you can gain in download speed?

    1. Martin Angelov says:

      Yes there will be a cache miss penalty, but this will only occur on the first visit of a website with the latest version. This can easily be compensated by the new features that are available in the new versions of the library, and the performance improvements. But if you have built your website with a specific version of jQuery, it could take a lot of work migrating to the latest version.

  20. Bryan Sheperd says:

    Great tips. I'm gonna use them ASAP. But, what about new waves of technology coming? take Navigation Timing into account for example. How, and when jQuery plans to support them?

  21. Darryl says:

    The .delay() between animations just gave me so much ideas, just never though to use it that much. Dont forget to kill animation queue with .stop() before each .animate.

    like so: $('#elem').stop().animate({width:200}).delay(2000).stop().animate({marginTop:100});

  22. Cliff says:

    How do webpages load above the fold content and then only load below the fold content if someone scrolls down the page?
    Or at least not display the images until they are in the display area of the monitor?
    What's that called?

    Thanks!

  23. Luke says:

    Good info. Big thanks must go out to the plugin developers for creating the tools that make development easier.

    And of course the JQuery developers.

  24. Mike says:

    Is local storage supported in all browsers? What the size limit?

  25. okan özkan says:

    Thank you for all tricks.

  26. Saurabh says:

    Really helpful article. I will definitely be using the ajax defaults to show loaders.

  27. I work with jQuery a year and learn a lot from blogs like yours, thank you and congratulations!!!!

  28. Aaron says:

    Thanks for this article!

    I had 1 question I'm hoping someone can answer, in regards to saving a jQuery object into a variable (ex: var $buttons = $('#navigation a.button');).

    Assuming, I have this wrapped in a function, like say on a button click, do I need to set this variable to null at the end of my function?

    var $buttons = null;

    Or can I assume the variable will be destroyed appropriately after the function leaves scope?

    Thanks!

  29. Aaron says:

    To respond to my own question - apparently you do NOT need to set the cached jquery variable to null within a function.

    The only time you would need to do that is if variable is global.

  30. Niks says:

    Thanks for sharing tips. I liked particularly about setting global settings. I was not aware of it

  31. Kingy says:

    Thanks, dude, This was helpful. :)

  32. Ofer says:

    Still relevant in 2012. This is a goldmine my friend. Thank you very much.

  33. Java dev says:

    These tips are fantastic and must read, thanks for sharing. Looking for some more.

  34. benz says:

    So grate article!! helpful!! thank you so much!!

  35. Nate Balcom says:

    Great post. I will be sharing this. I like your tip for delaying animations.

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text](http://example.com) for links