I have a situation in which i need to select all descendants of a certain element, but exclude those that are children of a container that equals the CSS class of the container i run my selector on.
Pretty complicated description.
<div class="container">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element">
<div class="container">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
</div>
Running a jQuery .find('.element') on the outermost DIV will get me all the DIVs, even the ones inside the second container. That is what i try to avoid.
Is there a quick and simple jQuery selector solution for this case?
I think what you want to use is the not selector. Like this..
$(".container").not(".container .container")
Alternately, you could use the children selector, to get the children from one level deep. Which would exlclude the nested divs.
To be a little more explicit, I think you'll want to use the not selector after you use the 'find'. Like this:
$(".container").find(".element").not($(".container .container .element"))
You can pass a function to not, so you could have that function look at the parents of each element match to see if it is nested inside of an element with the same class.
http://jsfiddle.net/QXfs2/6/
removeIfNested = function(index) {
// this is the corrent DOM element
var $this = $(this),
return_value = false;
$.each($this.attr('class').split(/\s+/), function(index) {
if ($this.parents("." + this).length > 0) {
return_value = default_value || true;
}
});
return return_value;
}
$(".container").find(".element").not(removeIfNested);
If you could add a class to the nested container, that would be ideal, then it's just:
$(".container").find(".element").not($(".nested .element"))
Assuming you added the class "nested", to your inner container div.
For your specific example this would work -
$("body > div.container > .element")
That will only get the top level element divs. If your element collection was in a different structure you could substitue body
with the collection's container id.
Demo - http://jsfiddle.net/QAP37/
You can use jquery selector like this:
find('*:not(.container .container *)')
I found the following slightly more succinct and general than the selected answer. It works with arbitrarily deeply nested trees:
function getNonNestedElements(container, elementSelector, containerSelector) {
return container.find(elementSelector).not(function(index) {
var nearest = $(this).closest(containerSelector);
return nearest[0] !== container[0];
});
}
where:
container
is the jQuery object for the root "container" div
elementSelector
is the jQuery selector for the element, .element
in this case
containerSelector
is the jQuery selector for the container, .container
in this case
So this finds all the elements beneath the initial container, then for each element checks to see if its nearest container is the initial container or some other nested container. If its nearest container is a nested container, it throws it out, so you are just left with descendants which are not inside another container.
Very handy for things like repeating multi-element, nested form fields.