Reputation: 4242
I would like to find all elements which match a selector but not if it is already contained in a matching element.
$('#container').find('.child').not('.child .child');
note that the .child elements are not necessary direct descendants.
why doesn't this work ?
I would like to select all element which would appear in $('#container').find('.child')
but exclude/filter()
any which would be in here $('#container').find('.child .child')
because one of its ancestors is a .child
var children = $('#container').find('.child').filter(function (i, el) {
return !$(el).closest('.child').length;
});
for some reason this doesn't work either JSFIDDLE
snippet adapted from @RonenCypis answer
var selector = ' .child ';
var children = $('#container').find(selector).filter(function(i, el) {
return !$(el).closest(selector).length;
});
children.css('background-color', 'blue');
#container div {
float: left;
display: inline-block;
width: 50px;
height: 50px;
color: #fff;
margin: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="child">one
<div class="child">one one</div>
</div>
<div class="child">two
<div class="child">two one</div>
</div>
<div class="child">three</div>
<div class="child">four
<div class="child">four one</div>
</div>
</div>
Upvotes: 4
Views: 816
Reputation: 12113
You can use parents
instead of closest
to find ancestors of the current element. closest
matches the current element in addition to ancestors.
var selector = ' .child ';
var children = $('#container').find(selector).filter(function(i, el) {
return !$(el).parents(selector).length;
});
children.css('background-color', 'blue');
#container div {
float: left;
display: inline-block;
width: 50px;
height: 50px;
color: #fff;
margin: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="child">one
<div class="child">one one</div>
</div>
<div class="child">two
<div class="child">two one</div>
</div>
<div class="child">three</div>
<div class="child">four
<div class="child">four one</div>
</div>
</div>
Upvotes: 1
Reputation: 21470
Demo in the JsFiddle
You can use filter()
for that:
HTML
<div id="container">
<div class="child">
<div class="child"></div>
</div>
<div class="child"></div>
<div class="child"></div>
<div class="child">
<div class="child"></div>
</div>
</div>
CSS
#container div {
display: inline-block;
width: 50px;
height: 50px;
margin: 10px;
background-color: red;
}
Javascript
var selector = '.child';
var children = $('#container').find(selector).filter(function(i, el){
return $(el).find(selector).length == 0;
});
children.css('background-color', 'blue');
This code will change the background color only for .child
elements that doesn't have additional .child
elements inside them.
Upvotes: -1
Reputation: 133403
You can use :has()
Selector in conjunction with :not()
selector
$('div').find('[role="tabpanel"]:not(:has([role="tabpanel"]))');
Upvotes: 1