5 Simple Tips for More Efficient jQuery Selectors
Posted on Jun 30, 2013
Remember, jQuery focuses on queries. The core of the library allows you
to find DOM elements using CSS selector syntax and run methods on that collection.
jQuery uses native browser API methods to retrieve DOM collections. Newer browsers (Chrome, Safari, Firefox) support getElementsByClassName, querySelector and querySelectorAll which parses CSS syntax. However, older browsers only offer getElementById() and getElementByTagName(). In the worst scenarios, jQuery's Sizzle engine must parse the selector string and hunt for matching elements.
Here are five tips which could help you optimize your jQuery Selectors.
Unfortunately, in older browser such as IE6/7, jQuery must examine every element on the page to determine whether "my_class" has been applied.
The selector will be more efficient if we qualify it with a tag name, e.g.
Consider the following complex selector:
p#intro must be unique so the selector can be simplified:
loads every em element into an array. It then works up the parents of each node and rejects those where p#intro cannot be found. The query will be particularly inefficient if you have hundreds of em tags on the page.
Depending on your document, the query can be optimized by retrieving the best-qualified selector first. It can then be used as a starting point for child selectors, e.g.
Remember jQuery offers chaining; multiple methods can be applied to the same collection. Therefore, the same code can be re-written so it applies to a single selector:
You should cache the jQuery object in a variable if you need to use the same set of elements multiple times, e.g.
Unlike standard DOM collections, jQuery collections aren't live and the object is not updated when paragraph tags are added or removed from the document. You can code around this restriction by creating a DOM collection and passing it to the jQuery function when it's required, e.g.
jQuery uses native browser API methods to retrieve DOM collections. Newer browsers (Chrome, Safari, Firefox) support getElementsByClassName, querySelector and querySelectorAll which parses CSS syntax. However, older browsers only offer getElementById() and getElementByTagName(). In the worst scenarios, jQuery's Sizzle engine must parse the selector string and hunt for matching elements.
Here are five tips which could help you optimize your jQuery Selectors.
1. Use an ID if Possible
HTML ID attributes are unique in every page and even older browsers can locate a single element very quickly:$("#myelement");
2. Avoid Selecting by Class Only
The following class selector will run quickly in modern browsers:$(".my_class");
Unfortunately, in older browser such as IE6/7, jQuery must examine every element on the page to determine whether "my_class" has been applied.
The selector will be more efficient if we qualify it with a tag name, e.g.
$(".my_class");jQuery can now restrict the search to DIV elements only.
3. Keep it Simple, please...
Avoid overly complex selectors. Unless you have an incredibly complex HTML code (document), it's rare you'll need any more than two or three qualifiers.Consider the following complex selector:
$("body #page:first-child article.main p#intro em");
p#intro must be unique so the selector can be simplified:
$("p#intro em");
4. Increase Specificity from Left to Right
A little knowledge of jQuery's selector engine is useful. It works from the last selector first so, in older browsers, a query such as:$("p#intro em");
loads every em element into an array. It then works up the parents of each node and rejects those where p#intro cannot be found. The query will be particularly inefficient if you have hundreds of em tags on the page.
Depending on your document, the query can be optimized by retrieving the best-qualified selector first. It can then be used as a starting point for child selectors, e.g.
$("em", $("p#intro")); // or $("p#intro").find("em");
5. Avoid Selector Repetition
It's rarely necessary to use the same selector twice. The following code selects every p tag three times:$("p").css("color", "red"); $("p").css("font-size", "1.3em"); $("p").text("New text changed!");
Remember jQuery offers chaining; multiple methods can be applied to the same collection. Therefore, the same code can be re-written so it applies to a single selector:
$("p").css({ "color": "red", "font-size": "1.3em"}).text("New text changed!");
You should cache the jQuery object in a variable if you need to use the same set of elements multiple times, e.g.
var $p = $("p"); $p.css("color", "red"); $p.text("New text changed!");
Unlike standard DOM collections, jQuery collections aren't live and the object is not updated when paragraph tags are added or removed from the document. You can code around this restriction by creating a DOM collection and passing it to the jQuery function when it's required, e.g.
var p = document.getElementByTagName("p"); $(p).css("color", "red"); // update the DOM $(p).text("Text changed!");
Top Useful jQuery Selectors
Selector | Example | Selects |
* | $("*") | All elements |
#id | $("#lastname") | The element with id="lastname" |
.class | $(".intro") | All elements with class="intro" |
.class,.class | $(".intro,.demo") | All elements with the class "intro" or "demo" |
element | $("p") | All <p> elements |
el1,el2,el3 | $("h1,div,p") | All <h1>, <div> and <p> elements |
:first | $("p:first") | The first <p> element |
:last | $("p:last") | The last <p> element |
:even | $("tr:even") | All even <tr> elements |
:odd | $("tr:odd") | All odd <tr> elements |
:header | $(":header") | All header elements <h1>, <h2> ... |
:animated | $(":animated") | All animated elements |
:focus | $(":focus") | The element that currently has focus |
:contains(text) | $(":contains('Hello')") | All elements which contains the text "Hello" |
:has(selector) | $("div:has(p)") | All <div> elements that have a <p> element |
:empty | $(":empty") | All elements that are empty |
:parent | $(":parent") | All elements that are a parent of another element |
:hidden | $("p:hidden") | All hidden <p> elements |
:input | $(":input") | All input elements |
:text | $(":text") | All input elements with type="text" |
:password | $(":password") | All input elements with type="password" |
:submit | $(":submit") | All input elements with type="submit" |
:reset | $(":reset") | All input elements with type="reset" |
:button | $(":button") | All input elements with type="button" |
:radio | $(":radio") | All input elements with type="radio" |
:checkbox | $(":checkbox") | All input elements with type="checkbox" |
:image | $(":image") | All input elements with type="image" |
:file | $(":file") | All input elements with type="file" |
:enabled | $(":enabled") | All enabled input elements |
:disabled | $(":disabled") | All disabled input elements |
:selected | $(":selected") | All selected input elements |
:checked | $(":checked") | All checked input elements |
Leave a comment: