Avoid bare class selectors in jQuery

Posted

It just happened again: I was looking at someone else's jQuery and I came across something like this:

$('.button').click(function() { /* do something */ });
This is a classic case of "just because you can, doesn't mean you should." This little bit of jQuery will, indeed, find every element on a page with a class of "button", but that's exactly the problem: it has to look at every element on the page to figure out which ones match the selector. It seems short and sweet, like so much of jQuery is, but on a page with a lot of elements, this selector can actually take a non-trivial amount of time to run. There are a few ways to avoid this:
  • If the element you're after has an ID attribute, use it. That's the single-fastest way to find an element. However, don't gratuitously add ID attributes to elements; the other methods below are perfectly good.
  • Specify the type of element you're after. For example, $('input.button'). This will tell jQuery that it's only looking for inputs, so it can disregard anything on the page that isn't an input. If you're looking for multiple element types, tell jQuery that: $('input.button, a.button')
  • Give jQuery some information about where to look for the element. For example: $('#myForm .button')
  • Use an element you've already found to tell jQuery where to find the element:
    var $ul = $('#myUnorderedList')
    var $li = $ul.find('.selected');

Filed under  //  jquery   optimization   selectors  
Comments (0)
Posted

More on jQuery selectors

Posted

Following up on my 13 seconds of selection hell: jQuery: what are the fastest selectors? Turns out that, as you might expect, $('div.class') is faster than $('.class'), and so is $('div').filter('.class'). Knowing where not to look ("skip anything that's not a div") helps make jQuery faster. To which you might say, "well duh." Regardless, the post above does a nice job of demonstrating it pretty plainly, and it's a good reminder that, if I'd wanted to stick with my attribute-based selection, I could have helped my code a little bit by telling it where I expected to find those attributes so it wouldn't have had to look through every element on a ridiculously huge page.

$('#data_entry input, #data_entry select').filter('[name=value]');

Filed under  //  javascript   jquery   selectors  
Comments (0)
Posted

13 seconds: Attribute vs. ID selectors in jQuery

Posted

Before:

// select all elements with an id or name attribute of fieldName;
// some are inputs (name attribute), some are td's (id attribute)
var $field = $('#' + fieldName + ', [name=' + fieldName + ']');
After:
// give inputs both a name and an id attribute, 
// and then just select fields and td's via id
var $field = $('#' + fieldName);
Savings: 13 seconds over the course of selecting > 100 elements. Thank god for Firebug's profiler, which pointed me to the problem in a few seconds. Attribute selectors in jQuery are handy, OK, but they don't seem to work for large-scale selections. A side note: vim made the HTML change easy, once I worked through its quirky regexp syntax which requires you to escape the +: s/name="\([^"]\+\)" /name="\1" id="\1" /g

Filed under  //  javascript   jquery   regexp   selectors   vim  
Comment (1)
Posted