How to Create Custom jQuery Pseudo-Selectors
jQuery allows developers to extend its selector engine using the
$.expr[':'] object to build custom pseudo-selectors. This
article explains how to define, configure, and execute custom
pseudo-selectors to streamline DOM traversal and eliminate repetitive
filtering code in your projects.
Understanding $.expr[':']
Under the hood, jQuery uses the Sizzle selector engine. The
$.expr[':'] object (an alias for
jQuery.expr.pseudos) stores all pseudo-selectors such as
:visible, :first, and :checked.
By adding a new function to this object, you define a custom filter that
jQuery applies to DOM elements during a query.
The callback function assigned to a custom pseudo-selector receives four arguments:
elem: The current raw DOM element being evaluated.index: The zero-based index of the element in the current collection.match: An array containing parsing metadata about the selector.match[3]contains any parameter passed inside the parentheses of the selector.stack: The complete array of elements being filtered.
The function must return true to keep the element in the
matched set, or false to exclude it.
Creating a Basic Custom Pseudo-Selector
A basic pseudo-selector evaluates an element's property without taking any arguments.
The following example creates a :blank-input selector
that matches input fields that are empty or contain only whitespace:
$.expr[':']['blank-input'] = function(elem) {
// Ensure the element is an input or textarea
if (elem.tagName === 'INPUT' || elem.tagName === 'TEXTAREA') {
return $(elem).val().trim() === '';
}
return false;
};
// Usage:
$('input:blank-input').addClass('error-highlight');Creating a Parameterized Pseudo-Selector
Custom selectors can also accept arguments passed within parentheses
(e.g., :min-height(200)). To capture the parameter, read
match[3].
The following example creates a :min-width selector to
filter elements whose rendered width meets or exceeds a specified pixel
value:
$.expr[':']['min-width'] = function(elem, index, match) {
// Parse the argument passed inside the parentheses: :min-width(value)
var minWidth = parseInt(match[3], 10);
if (isNaN(minWidth)) {
return false;
}
return $(elem).width() >= minWidth;
};
// Usage:
$('div:min-width(500)').css('border', '2px solid green');Best Practices
- Native JavaScript over jQuery Wrapping: Inside the
selector function, inspect
elemusing native JavaScript properties (e.g.,elem.getAttribute(),elem.offsetWidth) whenever possible. Avoiding$(elem)calls inside the function significantly improves selector performance across large DOM trees. - Compatibility: In modern jQuery (v1.8 and newer),
$.expr[':']is officially an alias for$.expr.pseudos. While$.expr[':']remains fully supported for backward compatibility, you can use$.expr.pseudosinterchangeably using the same syntax.