Here is my sample HTML:
<div id="parent1" data-attribute="parent">
<div id="child2" data-attribute="child">
<div id="grandchild4" data-attribute="child">
</div>
</div>
</div>
<div id="parent2" data-attribute="parent">
<div id="child3" data-attribute="child">
<div id="grandchild1" data-attribute="parent">
<div id="item1"></div>
</div>
</div>
<div id="child4" data-attribute="parent">
<div id="grandchild2" data-attribute="child">
<div id="grandchild3" data-attribute="parent">
<div id="item2" data-attribute="child">
<div id="sub1" data-attribute="child">
</div>
</div>
</div>
</div>
</div>
</div>
If the current element I'm performing query selection on is sub1
, how do I find the last ancestor with data-attribute="parent"
? In this case, the expected result should be parent2
.
I know closest()
will return the first match which would be grandchild3
, but is there like a selector to find the final ancestor? Querying by id
is not option, since my id's are dynamically created.
First, to find all the ancestors, you can combine two conditions [data-attribute="parent"]
and [id^="parent"]
. More on wildcard selectors
$('div[id^="parent"][data-attribute="parent"]')
Now, once you have all the ancestors, the last()
should give you the immediate one. Please find the snippet below
console.log($('div[id^="parent"][data-attribute="parent"]').last().attr('id'))
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <div id="parent1" data-attribute="parent"> <div id="child2" data-attribute="child"> <div id="grandchild4" data-attribute="child"> grandchild4 </div> </div> </div> <div id="parent2" data-attribute="parent"> <div id="child3" data-attribute="child"> <div id="grandchild1" data-attribute="parent"> grandchild1 <div id="item1">item1</div> </div> </div> <div id="child4" data-attribute="parent"> <div id="grandchild2" data-attribute="child"> <div id="grandchild3" data-attribute="parent"> grandchild3 <div id="item2" data-attribute="child"> item2 <div id="sub1" data-attribute="child"> sub1 </div> </div> </div> </div> </div> </div>
You can create your own version of closest
which will give you the last ancestor of the type you require. If you're using jQuery:
$.fn.extend({ closestTop: function(selection) { var el = this; var lastKnown = null; do { lastKnown = el; var guess = $(el).parent().length && $(el).parent().closest(selection || ''); el = guess && guess.length && guess.get(0) || null; } while (el;= null); return $(lastKnown); } }). console.log($('#sub1').closestTop('[data-attribute=parent]'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="parent1" data-attribute="parent"> <div id="child2" data-attribute="child"> <div id="grandchild4" data-attribute="child"> </div> </div> </div> <div id="parent2" data-attribute="parent"> <div id="child3" data-attribute="child"> <div id="grandchild1" data-attribute="parent"> <div id="item1"></div> </div> </div> <div id="child4" data-attribute="parent"> <div id="grandchild2" data-attribute="child"> <div id="grandchild3" data-attribute="parent"> <div id="item2" data-attribute="child"> <div id="sub1" data-attribute="child"> </div> </div> </div> </div> </div> </div>
You could write an XPath expression and evaluate that.
const element = document.querySelector('#sub1'); const xpath = 'ancestor::*[@data-attribute="parent"][last()]'; const result = document.evaluate(xpath, element, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; console.log(result);
<div id="parent1" data-attribute="parent"> <div id="child2" data-attribute="child"> <div id="grandchild4" data-attribute="child"> </div> </div> </div> <div id="parent2" data-attribute="parent"> <div id="child3" data-attribute="child"> <div id="grandchild1" data-attribute="parent"> <div id="item1"></div> </div> </div> <div id="child4" data-attribute="parent"> <div id="grandchild2" data-attribute="child"> <div id="grandchild3" data-attribute="parent"> <div id="item2" data-attribute="child"> <div id="sub1" data-attribute="child"> </div> </div> </div> </div> </div> </div>
It' right???
document.getElementById("sub1").addEventListener("click", function(){
let ancester = this.parentElement;
let flag = ancester.getAttribute("data-attribute");
while(flag !== "parent") {
ancester = ancester.parentElement;
flag = ancester.getAttribute("data-attribute");
}
console.log(ancester);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.