Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select all elements, except one and all its children using JavaScript?

With the following HTML, how can I select all divs at parent level only, except div with attribute - class="first" and its children using JavaScript?

In other words, after calling a query I want to get an array with these divs: class="all", class="second" and class="third".

<div class="all">
    <div class="header">All</div>
    <div class="cell-1"></div>
    <div class="cell-2"></div>
    <div class="cell-3"></div>
    <div class="cell-4"></div>
</div>
<div class="first">
    <div class="header">First</div>
    <div class="cell-1"></div>
    <div class="cell-2"></div>
    <div class="cell-3"></div>
    <div class="cell-4"></div>
</div>
<div class="second">
    <div class="header">Second</div>
    <div class="cell-1"></div>
    <div class="cell-2"></div>
    <div class="cell-3"></div>
    <div class="cell-4"></div>
</div>
<div class="third">
    <div class="header">Third</div>
    <div class="cell-1"></div>
    <div class="cell-2"></div>
    <div class="cell-3"></div>
    <div class="cell-4"></div>
</div>
like image 668
user2992672 Avatar asked Feb 05 '17 12:02

user2992672


2 Answers

These divs are children of some container (body at least, if not something more immediate). So you can use a selector with a child combinator and a :not clause for the .first element you don't want:

var divs = document.querySelectorAll("body > div:not(.first)");

Of course, if body isn't their container, replace that with a selector for the element that is.

Example:

var divs = document.querySelectorAll("body > div:not(.first)");
console.log("matching elements: " + divs.length);
Array.prototype.forEach.call(divs, function(div, index) {
  console.log(index + ": " + div.className);
});
<div class="all">
  <div class="header">All</div>
  <div class="cell-1"></div>
  <div class="cell-2"></div>
  <div class="cell-3"></div>
  <div class="cell-4"></div>
</div>
<div class="first">
  <div class="header">First</div>
  <div class="cell-1"></div>
  <div class="cell-2"></div>
  <div class="cell-3"></div>
  <div class="cell-4"></div>
</div>
<div class="second">
  <div class="header">Second</div>
  <div class="cell-1"></div>
  <div class="cell-2"></div>
  <div class="cell-3"></div>
  <div class="cell-4"></div>
</div>
<div class="third">
  <div class="header">Third</div>
  <div class="cell-1"></div>
  <div class="cell-2"></div>
  <div class="cell-3"></div>
  <div class="cell-4"></div>
</div>
like image 98
T.J. Crowder Avatar answered Oct 01 '22 22:10

T.J. Crowder


You'll need to build your CSS selector using the direct child combinator and the negation pseudo-class.

Vanilla JavaScript:

var divs = document.querySelectorAll("body > div:not(.first)");

jQuery:

var divs = $("body > div:not(.first)");

In the example above I'm assuming these divs are direct children of the body element, but if they aren't you can use the id or class of their parent instead:

<div id="container">
   //divs here
</div>     

would be:

document.querySelectorAll("#container > div:not(.first)");

and

<div class="container">
   //divs here
</div>     

would be:

document.querySelectorAll(".container > div:not(.first)");

The direct child combinator > only selects elements that meet criteria of the second selector (div for all div elements) and are only one level below the first selector (body for the body, #container and .container for the container div). Other elements additional levels below the first selector are ignored (e.g. <div class="header">Third</div> etc.).

The negation pseudo-class takes a simple selector as an argument (in this case .first) and excludes elements matching that selector from the results.

You can see a demonstration here: http://jsbin.com/puqosimigu/edit?html,js,console

like image 29
stephenlcurtis Avatar answered Oct 01 '22 22:10

stephenlcurtis