I created a snippet based on .parents() without jquery - or querySelectorAll for parents
function getParents (el, _class) {
let doc = document
let parents = []
let p = el.parentNode
while (p !== doc) {
let o = p
parents.push(o)
p = o.parentNode
}
parents.push(doc)
return parents[parents.map(x => x.className).indexOf(_class)]
}
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log(getParents(e, 'child4'))
})
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4 hello"> <!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
if <div class="child4 hello"> without hello I can get all child4, if hello or anything else is added, I am unable to get child4. I use indexOf() I think shouldn't be -1 or undefined. Could someone please correct me where is the error? Thanks
The problem is that you're getting a list of elements and you're mapping those to the elements' className, when the target element have more then just the child4 class, the value in the array will be child4 hello and when you're looking for the index of the child4 value in the array, the child4 hello won't match. Instead of Array.indexOf you can use Array.find.
function getParents (el, _class) {
let doc = document
let parents = []
let p = el.parentNode
while (p !== doc) {
let o = p
parents.push(o)
p = o.parentNode
}
parents.push(doc)
return parents.find(e => e.className.includes(_class))
}
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log(getParents(e, 'child4'))
})
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4 hello"> <!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
Instead of the getParents function you could use Element.closest
Here is an example:
const parents = Array.from(document.querySelectorAll('.child1')).map(e => e.closest('.child4'));
console.log(parents);
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4 hello">
<!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
As @Khauri mentioned, in the first example, instead of using the className property and using string functions to check if that value is a match, it will be better to use the classList property because it has a contains function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With