Reputation: 81
So I'm learning jQuery and encounter a function called parent() that allows you to access the parent of whichever element you've selected. So my question is why this function is there when we can select the parent element directly.
Upvotes: 1
Views: 587
Reputation: 13783
So my question is why this function is there when we can select the parent element directly.
You are presuming that you know exactly which unique (child) element you're holding, and therefore should know the exact parent element it has. But that's not a given.
Suppose I add the same click event handler to three wildly different elements (of the same class), in completely different parts of the DOM:
<div id="parent1">
<span id="child1" class="clickme" />
<div id="parent2">
<span id="child2" class="clickme" />
</div>
<ul>
<li id="parent3">
<a href="#" id="child3" class="clickme" />
</li>
</ul>
</div>
I've labeled the children and parents so you can clearly see that even though there are three different element with the same class, they each have a different parent.
Now consider the following click event:
$(".clickme").click(function() {
alert("the parent id of the clicked element is " + ???);
});
Focus on the ???
, how would you be able to find the correct parent element?
How would this click handler be able to know what the exact parent is, since it could be one of three elements (and thus one of three parents)?
If all you know is the child ($(this)
), then you ask the child who its parent is. That is exactly what $(this).parent()
does.
$(".clickme").click(function() {
var parentId = $(this).parent().attr("id");
alert("the parent id of the clicked element is " + parentId);
});
Upvotes: 0
Reputation: 178011
It is among other things very useful when you do NOT know the parent - especially when delegating
I personally prefer closest which also has found its way into vanilla JS
$(function() {
$("nav a").on("click",function(e) { // any "a" in nav
e.preventDefault();
const $parent = $(this).parent(); // $(this).closest("li")
const $grandParent = $(this).parent().parent(); // $(this).closest("ul");
$parent.toggleClass("active"); // toggle the containing li
$grandParent.toggleClass("activeUL",
$grandParent.find(".active").length>0 // if any active change the UL
);
})
})
.active {
background-color: yellow
}
.activeUL {
background-color: grey
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li><a href="">Click</a></li>
<li><a href="">Click</a></li>
<li><a href="">Click</a></li>
<li><a href="">Click</a></li>
</ul>
<ul>
<li><a href="">Click</a></li>
<li><a href="">Click</a></li>
<li><a href="">Click</a></li>
<li><a href="">Click</a></li>
</ul>
</nav>
Upvotes: 1
Reputation: 1074475
For at least three reasons:
Because of the set-based nature of jQuery. parent()
returns a set of the parent elements of the elements in the jQuery set you call it on. It doesn't just give you one element's parent like the parentNode
or parentElement
properties would (if you didn't use them in a loop).
Because you can pass it an optional selector so that if the parent doesn't match the selector, you get back an empty set.
Because it returns a jQuery set, not a raw element like you'd get from parentNode
or parentElement
. That means you can call jQuery methods on it, as Anuraag Vaidya points out.
Consider this code:
// Find `.a` elements
const a = $(".a");
// Find their parent elements
const parents = a.parent();
console.log(parents.length); // 2
// Find only their parent elements that match `.b`
const bParents = a.parent(".b");
console.log(bParents.length); // 1
<div>
<div class="a"></div>
</div>
<div class="b">
<div class="a"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You can see the set-based nature of jQuery working in the first parent()
call, which returned a set of two elements (because each .a
element is in its own parent).
You can see the filtering nature of it in the second result, since only one of the parent elements matched .b
.
Just FWIW, I don't find parent
very useful. closest
is more useful for the places I need something like it, and parents
(plural) is useful when I need the ancestry of an element.
Upvotes: 5
Reputation: 847
jQuery has traditionally provided methods that you can chain in order to perform various operations within a single line of code without having to use bunch of variables.
Let's take a simple example. If you have an element and you want to add 'red' class to the parent,'blue' class to its parent's parent, and then get the children of the original element's grand parent, you could write:
$('yourObject').parent().addClass('red').parent().addClass('blue').children()
To do this in plain JS, you would have to write much more:
let yourElement = <yourElementHere>;
yourElement.parentNode.setAttribute('class',yourElement.parentNode.getAttribute('class') + ' red');
yourElement.parentNode.parentNode.setAttribute('class',yourElement.parentNode.parentNode.getAttribute('class') + ' blue');
let uncles = yourElement.parentNode.parentNode.childNodes;
You're able to shorten your code quite a bit using parent()
function by placing it in a call chain.
Upvotes: 4