Just jQuery The Core UI - DOM Traversal Filters
Written by Ian Elliot   
Saturday, 27 August 2022
Article Index
Just jQuery The Core UI - DOM Traversal Filters
has
children, find, contents
Filter Functions

Filter Functions

As well as the standard filters you can easily create your own. The idea is that you pass in a function which is applied to each element in the results array. This is a very functional programming way of doing things, but it suits the situation perfectly.

The filter method that we have already encountered called with a selector can also be called with a function: 

.filter(function);

The function is called for each element in the results array and only if the function returns true is the element included in the new results array.

When the function is called it is passed the index of the element and the element itself. That is, the first parameter is the index and the second is the element.

For example the following function:

function odd(i){
 return i % 2==1;
}

tests for odd values. It is true if i is an odd number. You can use this to create a filter that removes all of the even index results:

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

or more usually:

$("p").filter(function(i){return i% 2==1;};

You can also make use of the element passed to perform more sophisticated filtering operations. 

For example:

function childP(i, ele) { 
 return ele.firstElementChild.nodeName == "P";
}

checks to see if the first child node of each element in the results is <p>. If it is then the element is left in the result. Notice that this function crashes if the element doesn't have a firstElementChild. You have to be careful when writing filter functions. 

The only problem with this idea is that jQuery provides you with all the methods you could want to find out anything about an element without having to resort to a custom function. In practice, you will usually find that there is a jQuery way of implementing any custom filter based on simple properties of the element. While you could use this to make changes to the element passed into the filter function, this would not be a particularly obvious use of the filter method which really should attempt to be a pure filter, i.e. just selecting elements.

If you want to make changes then use the each(function) iterator. It works in the same way but it doesn't perform a filter action on the results array, it simply applies the function. Although the return value isn't used to select elements, as it does in a filter, if you return false the iteration is terminated. 

For example:

$("p").each(function(i){$(this).append(i.toString());});

adds a paragraph number to the end of each paragraph. Notice that the element that this is set to is a DOM object not a jQuery object. If you want to use jQuery methods then all you have to do is wrap this using $(this) as a jQuery object first. 

If you want to get access to what the function processes, you can make use of a local variable:

var text=""; 
$("p").each(function(i){ text+=$(this).text(); });

When the iteration is complete the text of all of the paragraphs will be found in the text variable. 

The map(function) filter works like a cross between filter and the each iterator. In this case the function is called once for each item in the results array with the index and element as arguments. It returns an object to be included in a new jQuery results array. If you return an array of objects then all of them are inserted into the results array. If you return null or undefined no element is inserted. 

So for example:

$("p").map(function(i){ return this; });

returns the same jQuery result that $("p") produces. A useless operation, but it does illustrate the general idea.

Another way of picking out the odd elements is:

$("p").map(function(i){
if(i% 2==1) return this;
return null;
});

In other words, the element is returned if i is odd and null is returned if it is even. 

As a jQuery result array can contain plain JavaScript objects as well as DOM elements, you can use map to do things that you can't do with simple filtering or the each iterator. 

For example:

var result=$("p").map(function(i){
 return $(this).text();
});

returns a jQuery results array with the text of each paragraph as an element. To convert the jQuery results array into a standard array you can use the get() method:

resultarray=result.get();

or you could use get(i) or [i] to work with the individual elements. 

Example

Again we return to the generated web page introduced at the end of Chapter 3 with a repeated structure consisting of multiple divs:

     <div>
            <h1>First Item</h1>
            <p>long description of item.</p>
            <h2>Warning note</h2>
            <p>more text</p> 
            <hr>
     </div>

Let’s do the same job that we did in Chapter 3 – write a script that finds each warning paragraph and changes it to a new formulation, but this time using traversal filters. In Chapter 3 the solution was:

$("h2 + p").text("New warnings");

i.e. select <p> tags that immediately follow an <h2> tag.

We can write this another way using a traversal filter:

$("h2").next("p").text("New Warnings");

This first picks out all of the h2 elements and then uses the next filter to select all of the h2 elements that are immediately followed by a p element. The p elements are returned and the text function sets their text to the changed message.

Which is better?

If you are only doing this action a few times there is no need to worry about efficiency. You should use whichever one seems obvious to you. In this case there seems to be little to choose between them.

Summary

 

  • A traversal filter extends the idea of a filter to selectors that make use of the position in the DOM hierarchy of elements not in the current selection.

  • It also returns a result that is not simply a filtered version of the existing result.

  • That is a tree traversal filter process each element in the result and return a new jQuery result consisting of DOM objects that have a given relationship to the original elements in the results object in the current DOM tree.

  • The has filter function returns all of the elements in a result that have a descendant of the specified type, i.e. they contain an element of the specified type. 

  • The parent(selector) method filters the result object testing to see if the immediate parent of each one is selected by the selector. If it is then the parent that is selected is returned. 

  • The parents(selector) filters the results array only now selecting elements that have at least one parent of the specified type and it returns an array containing all of the parents.

  • The closest(selector) filter searches up the DOM tree looking for the first parent that matches the selector.

  • The parentsUntil(selector) method works exactly like parents, but it stops when the parent matches the selector. The results contain all the parents up to, but not including, the one that matched. 

  • OffsetParent returns the closest parent, i.e. the first found going up the set of containers, that is positioned – i.e. has a relative, absolute or fixed position attribute.

  • The children(selector) method gets the immediate children of each element in the array and filters them according to the selector.   

  • The find(selector) method extends the children method to return all of the children that match the selector not just the immediate children. 

  • The contents method returns all children including text nodes, comments and even the contents of iframes.

  • The siblings(selector) method selects all of the siblings of each of the elements in the array. 

  • The next(selector) and prev(selector) methods give you the next or previous siblings that match a selector if one is supplied. 

  • The nextAll(selector) and the prevAll(selector) work in the same way as next and prev respectively but they return an array with all of the next and previous siblings i.e, not just one of the two adjacent to the selected element. 

  • The nextUntil(selector,filter) and prevUntil(selector,filter) work in the same general way as parentsUntil. That is, nextUntil(selector,filter) extracts next siblings that match the filter until it finds a selector. prevUntil works in the same way but for previous siblings.

  • If you can’t find the filter that you need you can always use the filter function to define your own.

 

 Available as a Book:

smallcoverjQuery

buy from Amazon

  1. Understanding jQuery
  2. Basic jQuery CSS Selectors
       Extract: The DOM 
  3. More Selectors
       Extract: Basic Selectors 
  4. The JQuery Object 
  5. Filters 
  6. DOM Traversal Filters 
  7. Modifying DOM Objects
       Extract: Modifying The DOM 
  8. Creating Objects & Modifying The DOM Hierarchy
  9. Working With Data
  10. Forms
  11. Function Queues ***NEW!!!
  12. Animation
  13. jQuery UI
  14. jQuery UI Custom Control
  15. jQuery Plugins
  16. Testing With QUnit
  17. Epilog A Bonus Function

Also Available:

jquery2cover

buy from Amazon

 

Banner
 

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

 

picobook

 



 

Comments




or email your comment to: comments@i-programmer.info

<ASIN:1871962501>

<ASIN:1871962528>

<ASIN:1871962560>

 

 

 



Last Updated ( Saturday, 27 August 2022 )