Getting Started With jQuery - Filters
Written by Ian Elliot   
Saturday, 25 October 2014
Article Index
Getting Started With jQuery - Filters
Simple filters


justjquery

Meet The Filters

As well as the eq() filter there are also a number of other index based filters.

Unfortunately, they don't all come in two versions, method and selector, and this makes the list less regular than it could have been. 

 

:eq(i) or .eq(i)     filters the element with index i
:lt(n)  or .slice(0,n)   filters all elements from 0 to <n
:gt(n) or .slice(n+1) 

  filters all elements from  I>n 
  to the end of   the array

:first  or .first()     same as eq(0)
:last  or  .last()   same as eq(-1)
:even or .filter(":even")    selects all elements with even index
:odd  or  .filter(":odd")     selects all elements with odd index

                    

You can use negative indexes to work from the end of the array rather than the start. 

Some of these filters are worth looking at in more detail.

:lt, :gt and Slice

Although the :lt and :gt filters do not have method equivalents there is a method that does both of their jobs and more:

.slice(start,end)

returns the portion of the array from start to end. An important point is that the element specified by end isn't included in the filtered set. That is .slice(1,4) filters elements 1, 2 and 3 but not 4.

If you don't specify end then it returns from start to the end of the array.

You can easily see that, as indicated in the table;

.slice(n+1) is the same as :gt(n)

and

.slice(0,n) is the same as :lt(n)

If you want to be complete then .slice(i,i+1) is the same as .eq(i) but it is better to use .eq. 

In general it is better to use a standard CSS selector to extract an array of DOM objects and then use .slice to pull out the elements you really want than to use :gt and :lt because CSS selectors are faster than ones modified by :gt and :lt.

Filter

The filter(selector) method is really powerful because it can be used to convert any selector into a filter. Notice that you can write any valid selector as the argument to filter and it will be applied to each of the array elements in turn and a new results array will be constructed consisting of only those elements that are selected. 

For example:

$("div,p").filter("p");

first creates a result array that has either dive or p elements. The filter then removes everything that isn't a p i.e. it produces the result you would have got if you did $("p").

Notice that the filter method only examines the each DOM element in the array there is no further searching of the DOM to find elements that match. For example, $("p") returns an array of all of the paragraph elements in the document but .filter("p") returns only the paragraph elements already in the result set.

Filter is a powerful method and you can quickly become very relient on making use of it. It also has another form where you can supply a function that does the filtering and this is described in the next chapter on advanced filtering.   

:odd and :even

It is odd, pun intended, that :even and :odd don't have method equivalents. There is no obvious reason for this but given the .filter method can convert any selector into a filter this isn't a problem. For example:

$("p").filter(":odd");

returns a jQuery array of odd indexed paragraph elements and

$("p").filter(":even");

returns a jQuery array of even indexed paragraph elements.

 

Not Filters

As well as these index based filters there are a few that are based on other conditions. The not filters are perhaps the most potentially confusing because what they do is in principle simple but there are some important differences between :not() and .not()

The idea is very simple:

:not(selector) or .not(selector)

both filter a selection to the elements that do not match the selector. Of course in both cases you have to be careful what the set is that the "not" is applied to. 

For example:

$("p,div:not(div)").append("<p>Hello2</p>");

selects all p and div elements and then filters out the div elements - a pointless exercise but it demonstrates the idea. The expression

 $("p,div").not("div").append("<p>Hello2</p>");

does exactly the same job but the initial query returns an array of p and div elements first. 

You can use any selector in the not filter and this potentially makes it very complicated. Also notice the obvious fact that you don't enclose the selector in :not in quotes - the whole thing is already in quotes.

It is also better to use .not because :not isn't a standard selector and so can be slower.

The .not method has some additional ways it can be called. In particular you can specify another jQuery object to be removed and you can specify a function to determine what to remove.

The Add Filter

The add filter is a little strange in that it doesn't remove elements from the results array it adds them.

There are a number of forms of this filter depending on what you give it to specify what should be added. 

You can use any jQuery selector and the results will be added to the existing results array.

That is the:

.add(selector)

method adds the jQuery object that results from evaluating the selector to the existing selection. The complication is that the selector can be almost anything that would create a jQuery result when used in $(selector).

So for example

$("p").add("div");

adds all the div elements in the document to the array of p elements. That is it gives you the same result as:

$("p,div")

It is surprising that the add method performs a full selection on the document and this makes it more powerful than you might expect.

A simpler use of the add method is to add existing or constructed objects. For example:

result3=result1.add(result2);

will add the elements in result2 to the elements in result1 to give a unified result list. 

You can also add constructed objects using HTML:

$("p").add("<p>"hello"</p>");

adds the HTML as an element to the results array as a new results array.

The add method can sometimes be useful when you are trying to build up a list of elements that satisfy complex conditions.  

Other Filters

There are a range of other filters which have been added to jQuery in a fairly ad-hoc way. They are useful but they don't fit into any neat patterns or families - they are just useful.

:animated

selects elements in the process of animation at the time the selector is run. Clearly this one isn't really a filter on the results array as it is tied to the time that the query is run. However it is still faster to use

.filter(":animated")

:focus 

selects the element that has the current focus. Again this isn't really a filter on the result array because it matters when the query is run. 

:header 

selects all header elements h1,h2 and so on. This one is convertible to a true filter and it is better to use

.filter(":header")

:lang(language)

Selects all elements with a language attribute as specified. It also extracts elements contained within language specific elements on the assumption that they inherit the language setting unless it is overridden.

:root

Selects the root element of the document - usually html.

:target

Selects the element with the id that matches any fragment identifier in the URL. That is if the URL is www.mysite.com/#mycontrol   then :target selects the element, if any, with an id of mycontrol. 

There are more miscellaneous filters but the line between filter and selector starts to be increasingly blurred.

After all is :header a selector or a filter?  

There is a tendency in jQuery to call any non-standard selector a filter and this can be confusing. 

Filter Strategies

One of the most confusing things about filters is that it is often possible to do the same job with a selector. For example you might start out with a selector that picks out all of the div and p elements and then filter the result down to just the p elements. Clearly you could have extracted just the p elements in the first place. 

If you have a choice of how to obtain a particular result then there are a number of things that should guide you.

The first is to use standard CSS selectors in preference to jQuery extended selectors. Standard CSS selectors are supported by the browser and much faster. 

It is generally faster to search the entire DOM as few times as possible. This means that if you can extract a result array and then use a filter to narrow it down to what you want this is likely to be faster. The filter only accesses the elements of the results array and not the entire DOM. 

Obviously if you can extract a results array once and get different sub-sets from it by applying a filter this is going to be faster.

There are also times when only a filter will do the job. For example, if you want to get the text from the first ten paragraphs in a document you have to use either:

$("p:lt(10)").text();

or

$("p").slice(0,10).text();

Both of which return the concatenated text of the first 10 paragraphs.  

Which is best?

The answer depends on the number of paragraphs in the entire document. The first performs a slow non CSS standard selector on the text but the second extracts all of the paragraph elements which could number thousands and then reduces it to just ten.  

In practice there seems to be little difference between the two using a modern browser.   

  

jquerycover

Chapter List 

  1. The DOM
  2. CSS Selectors
  3. Filters
  4. Advanced Filters
  5. Manipulating The DOM
  6. Promises & Deferred
  7. Promises, Deferred & WebWorkers
  8. Ajax the Basics - get
  9. Ajax the Basic -  post
  10. Ajax - Advanced Ajax To The Server 
  11. Ajax - Advanced Ajax To The Client
  12. Ajax - Advanced Ajax Transports And JSONP
  13. Ajax - Advanced Ajax The jsXHR Object
  14. Ajax - Advanced Ajax Character Coding And Encoding
  15. jQuery - Easy Plugins
  16. jQuery UI
  17. jQuery UI Custom Control - Widget Factory
  18. Getting Started With QUnit Testing

To be informed about new articles on I Programmer, install the I Programmer Toolbar, subscribe to the RSS feed, follow us on, Twitter, Facebook, Google+ or Linkedin,  or sign up for our weekly newsletter.

 

Banner


JavaScript Jems - Objects Are Anonymous Singletons

JavaScript should not be judged as if it was a poor version of the other popular languages - it isn't a Java or a C++ clone. It does things its own way.  In particular, every object can be regard [ ... ]



JavaScript Canvas - Typed Arrays

Working with lower level data is very much part of graphics. This extract from Ian Elliot's book on JavaScript Graphics looks at how to use typed arrays to access graphic data.


Other Articles

 



Last Updated ( Tuesday, 09 August 2016 )