Saturday, June 19, 2010

jQuery: Understanding Selectors to Improve Performance

6/19/2010

Most likely, you are familiar with the basic CSS selectors that jQuery provides, but unless you've done some digging, you might not be aware of some of the more advanced selectors. I’ll start off by describing ones you are aware of, and then we’ll branch out. In addition to the actual selectors, I’ll touch on some other concerns you should be aware of.

Understanding Selectors

Simple Selectors

Here are examples of simple selectors:
//Selects all the anchor tags in the DOM
$('a')

//Selects all the anchor tags inside of div elements in the DOM
$('div a')

//Selects all the elements with a class of 'odd'
$('.odd')

//Selects all the tr elements with a class of 'odd'
$('tr.odd')

Uncommon Selectors

Although jQuery supports CSS3 selectors, many Web developers are seemingly unaware of these features, primarily because of the lack of CSS3 browser support, which understandably leads many developers to not use CSS3 selectors when they build their style sheets. Thankfully, jQuery has taken care of many cross-browser issues, and developers have made huge efforts to make their code work across a wide array of browsers, versions, and operating systems.
Here are some powerful CSS3 type selectors that you can comfortably use in your jQuery programs.
$("a[href$='mp3']") 
<!-- Selects all links that ends with mp3 in the href -->

$("a[target='_blank']") 
<!-- Selects all links that are set to open a new window --> 

$("a[class^='custom']")
<!-- Selects all links that have a class that begins with "custom" -->

Advanced Selectors

In addition to the CSS3 selectors, jQuery has added more functionality to increase its flexibility in getting whatever element you are trying to select. Here are some examples:
$(':input') 
<!-- Selects all the input elements (text, password, radio, etc...) -->

$(':disabled') 
<!-- Selects all the disabled input elements -->

$('li:eq(3)') 
<!-- Selects the 4rd (0 based) list item -->

$('li > a[href$=pdf]')
<!-- Selects links to pdf files that are children of a list item-->

$('li:has(a)')
<!-- Selects list items that have links inside of them -->

Selector Context

Sometimes you want to select a set of DOM elements that are only from a particular area of your DOM. At first thought, you might try doing something like this:
$('span a.myClass').addClass('highlight');
Instead of searching through the whole DOM looking for your class, you can instead use an overloaded jQuery function and pass in the context where you want the selection to begin. This way, you are telling jQuery where to start, which can dramatically speed up the selection process. Here’s code that demonstrates this approach:
$('span a.myClass', '#myDiv').addClass('highlight');
<!-- Start at #myDiv context & use "span a" selector to find the link -->

Caching Selectors or Chaining

Seeing that jQuery selection is at the heart of most jQuery code, you should take notice of what your performance is like. A common technique to help with performance is to cache your selections if you plan to use them again later in your code.
The following shows an example of what an uncached code snippet might look like:
$('#myButton').click(function() {
   $('#alertMessage').hide();
   $('#alertMessage').html('<strong>Really Bad Error</strong>');
   $('#alertMessage').fadeIn('slow');
});
This example selects the alertMessage element on three separate occasions to perform simple operations. The performance hit of this code is minimal because it is only selecting three elements by their ID, but imagine if you were trying to select elements using a complex selector, such as $('li > a[href$=pdf]'), and you were performing operations inside a loop 100 times. I think you get my point. So, let’s rewrite the preceding code, but this time cache our selection:
$('#myButton').click(function() {
   var $alertMessage = $('#alertMessage');
   $alertMessage.hide();
   $alertMessage.html('<strong>Really Bad Error</strong>');
   $alertMessage.fadeIn('slow');
});
The only difference is that I introduced a new variable and saved the jQuery object from the selector's results.
Instead of caching as shown in the previous example, you can chain your actions together since each function returns the referring jQuery object. Let's change the previous code snippet to use chaining:
$('#myButton').click(function() {
   $('#alertMessage').hide()
      .html('<strong>Really Bad Error</strong>')
      .fadeIn('slow');
});
As you can see, you don’t need to store the results of the selector because you can just chain off the jQuery object returned from one function to another. The result is faster, cleaner code that is easier to read.

Written by

Arvind is a web developer, programmer and blogger. He has expertise in PHP, Magento, WordPress, jQuery, JavaScript, HTML5 and CSS3. He loves to develop good looking websites with strong backend.

1 comments :

  1. I would love to know more about programming and technical related things. I appreciate for sharing the information with us. Hope, you keep updating it.

    ReplyDelete

We would love to hear from you...

 

© 2014 Web Speaks . All rights resevered. Designed by Templateism