In this excerpt from jQuery Cookbook the authors explain how to create a custom fiter selector to target specific elements when using the jQuery Javascript library.
If you need a reusable filter to target specific elements
based on their characteristics, you can extend jQuery’s selector expressions under the jQuery.expr[':'] object; this is an alias for
Sizzle.selectors.filters. Each new
filter expression is defined as a property of this object, like
so:
jQuery.expr[':'].newFilter = function(elem, index, match){
return true; // Return true/false like you would on the filter() method
};
The function will be run on all elements in the current collection and needs to return true (to keep the element in the collection) or false (to remove the element from the collection). Three bits of information are passed to this function: the element in question, the index of this element among the entire collection, and a match array returned from a regular expression match that contains important information for the more complex expressions.
For example, you might want to target all elements that have a certain property. This filter matches all elements that are displayed inline:
jQuery.expr[':'].inline = function(elem) {
return jQuery(elem).css('display') === 'inline';
};
Now that we have created a custom selector, we can use it in any selector expression:
// E.g. #1
jQuery('div a:inline').css('color', 'red');
// E.g. #2
jQuery('span').filter(':not(:inline)').css('color', 'blue')
jQuery’s custom selectors (:radio,
:hidden, etc.) are created in this way.
As mentioned, the third parameter passed to your filter function is an array returned from a regular expression match that jQuery performs on the selector string. This match is especially useful if you want to create a filter expression that accepts parameters. Let’s say that we want to create a selector that queries for data held by jQuery:
jQuery('span').data('something', 123);
// We want to be able to do this:
jQuery('*:data(something,123)');
The purpose of the selector would be to select all elements that
have had data attached to them via jQuery’s data() method—it specifically targets elements
with a datakey of something, equal to the number
123.
The proposed filter (:data) could be created as follows:
jQuery.expr[':'].data = function(elem, index, m) {
// Remove ":data(" and the trailing ")" from
// the match, as these parts aren't needed:
m[0] = m[0].replace(/:data\(|\)$/g, '');
var regex = new RegExp('([\'"]?)((?:\\\\\\1|.)+?)\\1(,|$)', 'g'),
// Retrieve data key:
key = regex.exec( m[0] )[2],
// Retrieve data value to test against:
val = regex.exec( m[0] );
if (val) {
val = val[2];
}
// If a value was passed then we test for it, otherwise
// we test that the value evaluates to true:
return val ? jQuery(elem).data(key) == val : !!jQuery(elem).data(key);
};
The reason for such a complex regular expression is that we want to make it as flexible as possible. The new selector can be used in a number of different ways:
// As we originally mused (above):
jQuery('div:data("something",123)');
// Check if 'something' is a "truthy" value
jQuery('div:data(something)');
// With or without (inner) quotes:
jQuery('div:data(something, "something else")');
Now we have a totally new way of querying data held by jQuery on an element.
If you ever want to add more than one new selector at the same
time, it’s best to use jQuery’s extend() method:
jQuery.extend(jQuery.expr[':'], {
newFilter1 : function(elem, index, match){
// Return true or false.
},
newFilter2 : function(elem, index, match){
// Return true or false.
},
newFilter3 : function(elem, index, match){
// Return true or false.
}
});
Learn more about this topic from jQuery Cookbook.
Getting started with the jQuery library is easy, but it can take years to fully realize its breadth and depth; jQuery Cookbook shortens the learning curve considerably. You'll learn patterns and practices from 19 leading developers who use jQuery for everything from integrating simple components into websites and applications to developing complex, high-performance user interfaces. The recipes start with the basics and then move into practical use cases with tested solutions to common web development hurdles.

Help





