Use jQuery to get descendants of an element that a

2020-06-07 05:03发布

问题:

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?

回答1:

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.



回答2:

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/



回答3:

You can use jquery selector like this:

find('*:not(.container .container *)')


回答4:

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.