Understanding the jQuery $.expr Object
The jQuery $.expr object is the internal storage
mechanism for jQuery's selector engine, historically powered by Sizzle.
It defines how jQuery parses, interprets, and matches elements against
CSS selectors. By interacting directly with $.expr,
developers can extend jQuery's native selection capabilities and create
custom pseudo-class selectors tailored to specific application
needs.
What is $.expr?
In jQuery, standard selectors like #id,
.class, or div are processed using standard
DOM methods like querySelector or
querySelectorAll. However, jQuery also supports custom,
non-standard pseudo-selectors such as :visible,
:hidden, :input, and :even.
These custom pseudo-selectors are registered within the
$.expr object. Specifically, $.expr[':'] (an
alias for $.expr.pseudos in jQuery 1.8 and later) holds the
collection of selector functions that jQuery evaluates when scanning DOM
nodes.
The Primary Purpose: Creating Custom Selectors
The main practical purpose of $.expr for developers is
creating custom pseudo-selectors to simplify repetitive filtering logic.
Instead of chaining methods like .filter(), you can embed
the logic directly into selector strings.
Basic Syntax and Example
A custom selector is created by attaching a new function to
$.expr[':']. The function must evaluate an element and
return true if it matches, or false if it does
not.
Here is an example that creates a :caseContains
selector, allowing case-insensitive text matching:
jQuery.expr[':'].caseContains = function(elem, index, match) {
var searchText = match[3];
return (elem.textContent || elem.innerText || "")
.toLowerCase()
.indexOf(searchText.toLowerCase()) >= 0;
};
// Usage:
$('p:caseContains("jquery")').addClass('highlight');Anatomy of a Selector Function
When defining a custom selector in $.expr, the callback
function receives several arguments:
elem: The current DOM element being tested.index: The zero-based index of the element within the loop.match: An array containing regex match information. The most commonly used element ismatch[3], which captures any parameter passed inside the parentheses of the pseudo-selector (e.g., the"jquery"in:caseContains("jquery")).
Why Use $.expr?
- Code Readability: Custom selectors make queries
declarative and clean (e.g.,
$('a:external')instead of running loops or custom.filter()checks). - Reusability: Once added to
$.expr, the selector is globally available throughout your application wherever jQuery selectors are accepted. - Component-Level Filtering: You can create
domain-specific selectors, such as
:overdue,:validated, or:inline, making DOM traversal intuitive for teams working on large codebases.