We can use jQuery methods to retrieve (select) one or more elements from the DOM tree. Let us start by providing some of these jQuery methods in the following table:
Method | Retrieves |
---|---|
.parent() | the parent node of the element (or elements) |
.parents() | all ancestors of the element (or elements) |
.closest() | the first ancestor of the element that matches the passed selector |
.children() | all child nodes that match the passed selector |
.find() | all descendants of the element (or elements) that match the passed selector |
.siblings() | all sibling nodes of the element (or elements) |
Before we begin describing above methods, let us use a simple HTML page as a basis. The page provided below has an ordered list that contains three list elements.
<!doctype html> <html> <body> <ol> <li id="idPhys" class="twoTimesWinner">Marie Curie</li> <li id="idChem" class="twoTimesWinner">Marie Curie</li> <li id="idPeace">Mother Teresa</li> </ol> </body> </html>
The .parent() method returns the immediate parent node of the element or the elements. Thus in the above example, $("ol").parent() would return the parent element of the $("ol") element, which is the $("body") node.
The .parents() method comes with a bigger net and returns all the parent nodes (aka ancestors) of the element or the elements. Thus, the $("ol").parents() would return two elements: $("body") and $("html"). This method starts at the parent of the element that invokes this method and then, traverses upwards, until it reaches the root of the tree.
The .closest() method returns the closest ancestor that matches the passed selector criteria; it is mandatory to pass the selector criteria. This method is in some ways similar to the .parents() method since it traverses upwards. However, unlike the .parents() method, this method starts at the current element itself that invokes it. Also, unlike the .parents() method, this method returns only one parent (provided it finds one!). If we do not pass any selection filter to the .closest() method, then the result is undefined.
The .children() method locates all the immediate child nodes that match the passed selector criteria. Thus, $("body").children("ol") will return all the <ol> nodes that are immediate child nodes of the $("body") element. And, if we do not specify any filter, then it selects all child nodes.
While the .children() method returns only immediate child nodes, the .find() method selects all the descendant nodes of the passed element that match the criteria. Thus, $("body").find("li") will return all the <li> element present in the body. In the above example, we start at the $("body") DOM element, traverse all descendant nodes -- not just immediate children -- and return all nodes that match the criteria.
The .siblings() method returns all the siblings of the current element that match the provided selector criteria. It returns all siblings, if we do not provide any selector criteria. In the above example, $("li #idPhys").siblings() would retrieve the list element with the (unique) CSS ID "idPhys" (the first element) and then return all of its siblings. These siblings would be the remaining two list elements. On the other hand, $("li #idPhys").siblings("#idChem") would return only one sibling, since we are now more specific.
Now that we are familiar with some of the retrieval methods, let us move on and go through some examples. These examples use a similar HTML structure as that of the earlier example.
Our first example focuses on the parent/ancestor related methods. For the sake of identifying the retrieved nodes in the output, we add CSS ID to some of the elements -- this allows us to print the CSS ID of the retrieved nodes using the .attr("id") method. In real-life code, there would typically be no need to assign CSS IDs to some of these elements like head, body, etc. So, if you think that adding CSS IDs to some of these elements is far-fetched, well, then you are not alone!
<!doctype html> <html id="idHtml"> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> </script> <body id="idBody"> <div id="idTitle">Nobel Laureates:</div> <ol id="idOl"> <li id="idPhys" class="classFoo">Marie Curie (Physics, 1903)</li> <li id="idChem" class="classFoo">Marie Curie (Chemistry, 1911)</li> <li id="idPeace">Mother Teresa (Peace, 1979)</li> </ol> <script type="text/javascript"> $(document).ready(function() { // Get the parent of the <li> element with CSS ID "idPhys". var str = '$("#idPhys").parent(): ' + $("#idPhys").parent().attr("id") + "<br>"; // Get all parents of the <li> element with CSS ID "idPhys". $("#idPhys").parents().each(function(indx, elem) { str += '<br>$("#idPhys").parents(): ' + $(elem).attr("id"); }); // Get closest() for the <li> element with CSS ID "idPhys". str += "<br><br>"; str += '$("#idPhys").closest("body"): ' + $("#idPhys").closest("body").attr("id"); str += '<br>$("#idPhys").closest("html"): ' + $("#idPhys").closest("html").attr("id"); str += '<br>$("#idPhys").closest(): ' + $("#idPhys").closest().attr("id"); // Append the text to the body element. $("body").append(str); }); </script> </body> </html>
Let us now load the above page. Among other things, the output (provided below) confirms that while the .parent() method returns the immediate parent node and the .parents() method returns all the ancestors. We also see that if we do not pass any filter to the .closest() method, then the result is undefined.
Our second example focuses on the children/sibling related methods. Accordingly, it focuses on finding child elements of the "<ol>" element and the siblings nodes of one of the "<li>" nodes.
<!doctype html> <html> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> </script> <body> <div class="classTitle">Nobel Laureates:</div> <ol id="idOl"> <li id="idPhys" class="classFoo">Marie Curie (Physics, 1903)</li> <li id="idChem" class="classFoo">Marie Curie (Chemistry, 1911)</li> <li id="idPeace">Mother Teresa (Peace, 1979)</li> </ol> <script type="text/javascript"> $(document).ready(function() { var str = ""; // Get all children of the <ol> element with CSS ID "idOl". $("#idOl").children().each(function(indx, elem) { str += '<br>$("#idOl").children(): ' + $(elem).attr("id"); }); // Find among the children of the <ol> element with CSS ID "#idPeace". str += "<br><br>"; str += '$("#idOl").find("#idPeace"): ' + $("#idOl").find("#idPeace").attr("id"); // Get all siblings of the <li> element with CSS ID "idChem". str += "<br>"; $("#idChem").siblings().each(function(indx, elem) { str += '<br>$("#idChem").siblings(): ' + $(elem).attr("id"); }); // Append the text to the body element. $("body").append(str); }); </script> </body> </html>
Here is the output when we load this page:
For cases where DOM returns a list of elements, we can use several jQuery filters to select a subset from the list. jQuery provides various types of selector filters (pseudo-selectors) to do that:
Filter | Return Value(s) |
---|---|
$(:first-child) | the first child node(s) of the passed parent(s) |
$(:last-child) | the last child node(s) of the passed parent(s) |
$(:nth-child(n)) | the nth child node(s) of the passed parent(s) |
$(:only-child) | all elements that are the only child of the passed parent(s) |
$(:parent) | all elements that have at least one child element |
$(:empty) | all elements that have no child elements |
For the above filters we would need to provide the selector just prior to these filters. Thus, "$(image :first-child)" would select the first image from the list of all images. Likewise, if there are multiple parents, then the ":first-child" will return the first child node from all the parents. Similarly, "$(image :last-child)" would select the last image from the list of all images.
The ":nth-child(n)" means that if a parent has K child nodes, then ":nth-child(n)" returns the nth child node, starting from the beginning. Thus, ":nth-child(1)" would select the first child and is similar to calling the ":first-child".
The ":parent" filter returns all nodes that are parents nodes (parent of any node!). The ":empty " filter returns all nodes that do not have any child nodes.
With that, let us see our last example to further understand these (DOM-specific) filters. The example uses the earlier HTML structure and applies filters when retrieving list elements.
<!doctype html> <html> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> </script> <body> <div>Nobel Laureates:</div> <ol id="idOl"> <li id="idPhys" class="classFoo">Marie Curie (Physics, 1903)</li> <li id="idChem" class="classFoo">Marie Curie (Chemistry, 1911)</li> <li id="idPhys2">Albert Einstein (Physics, 1921)</li> <li id="idPeace">Mother Teresa (Peace, 1979)</li> </ol> <div>Nobel Laureates who received the Award twice:</div> <ol> <li id="idCurieAwards"> Marie Curie (Physics(1903) and Chemistry(1911))</li> </ol> <script type="text/javascript"> $(document).ready(function() { // Get the first/last child element(s). var str = "[li:first-child] " + $("li:first-child").attr("id") + "<br>"; str += "[li:last-child] " + $("li:last-child").attr("id") + "<br>"; // Get the nth-child(n) element. str += "[li:nth-child(2)] " + $("li:nth-child(2)").attr("id") + "<br>"; // Get the only-child element. str += "[li:only-child] " + $("li:only-child").attr("id") + "<br>"; // Get all parent elements that have class as classFoo. str += "<br>"; $(".classFoo:parent").each(function(index, elem) { str += "[.classFo:parent]: " + $(elem).attr("id") + "<br>"; }); // Append the text to the body element. $("body").append(str); }); </script> </body> </html>
Here is the output when we load the above page: