Reputation: 119
I need to find a way to select a DOM element that shares the closest common ancestor with a given element.
Here's what I mean:
<div class="grandparent">
<span class="match not-this-one">
<div class="parent">
<span class="match this-one">
<div class="container">
<span class="me">
</div>
</div>
I want something that does this:
$('.me').closestCousin('match'); selects <span class="match this-one">
closest() and parent() select ancestors, but don't look for cousin elements.
Upvotes: 0
Views: 469
Reputation: 651
$('.me').closest(':has(.match)').find('.match')
Selects the closest common ancestor (the closest element containing a descendant with matching class). And then selects the matching descendant(s). The search is for any descentants, not children only!
.match one would be found here.
to get .match two in above case, run:
$('.me').parents().children('.match').first()
select all ancestors (closest listed first), then get their children matching the criteria. Take the 1st one since this is the closest one.
Upvotes: 0
Reputation: 10924
I think your best bet is to write a recursive function that combines the use of .prev()
and .parent()
to find your closest cousin.
Edit: I misunderstood the question. This solution searches up the tree to find the closest target, and as a byproduct of its implementation will also find siblings to the original element.
function closestCousin(me, target) {
var cousin = me.prev(target);
if (cousin.length) {
return cousin;
} else {
var parent = me.parent();
if (parent.length) {
return closestCousin(parent, target);
} else {
return parent;
}
}
}
var me = $(".me");
closestCousin(me, ".match").css("color", "red");
closestCousin(me, ".match2").css("color", "blue");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="grandparent">
<span class="match match2 not-this-one">Don't Match</span>
<div class="parent">
<span class="match this-one">Match</span>
<div class="container">
<span class="me">Me</span>
</div>
</div>
</div>
Upvotes: 1
Reputation: 1
You can use .closest()
with selector :not(.me)
to exclude current element from being matched by .closest()
; siblings()
with selector .match
$(".me").closest(":not(.me)").siblings(".match").addClass("matched")
.matched {
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="grandparent">
<span class="match not-this-one">not-this-one</span>
<div class="parent">
<span class="match this-one">match this-one</span>
<div class="container">
<span class="me">me</span>
</div>
</div>
Upvotes: 1
Reputation: 15786
This should work: $('.me').closest('.match');
But it only goes up the DOM tree. If that's what you need,
Upvotes: 0