johntrepreneur
johntrepreneur

Reputation: 4694

css selector to exclude certain descendants and their descendants of jquery object?

Given a jquery object that has many levels of descendants, how do you exclude certain descendants AND their descendants? Assume there is a class (.foo in this case) on the top node of the elements intended for exclusion and your jquery object is the div1 below.

EDIT: Clarification: I want to exclude ALL descendants of .foo and not just the immediate children.

Example where we want to exclude <code>.foo</code> nodes

$('#button1').click(function() {
  var selector = '#test ' + $('#input1').val();
  var numberElements = $(selector).length;
  $('#numberElements').text(numberElements);
  var elementsAsCommaSeparatedList = _.pluck($(selector), 'id');
  $('#elementList').text(elementsAsCommaSeparatedList.join(', '));
});
#input1 {
  width: 230px;
  font-size: 16px;
  font-weight: bold;
}

#numberElements,
#elementList {
  color: green;
  font-weight: bold;
  font-size: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label for="input1">Please supply a selector... $('<input id="input1" value="div:not(.foo, .foo *)"></label>')
<button id="button1">Apply Selector</button>
<div>(default value is from @DaniP's answer)</div>
<div id="result"><span>Number of elements selected:  </span><span id="numberElements">0</span></div>
<div>
  <span>Elements selected (by id):</span>
  <span id="elementList"></span>
</div>
<div id="test">
  <div id="div1">
    <div id="div2">
      <div id="div4">
        <div id="div8"></div>
        <div id="div9"></div>
      </div>
      <div id="div5" class="foo">
        <div id="div10"></div>
        <div id="div11"></div>
      </div>
    </div>
    <div id="div3">
      <div id="div6">
        <div id="div12"></div>
        <div id="div13"></div>
      </div>
      <div id="div7" class="foo">
        <div id="div14"></div>
        <div id="div15"></div>
      </div>
    </div>
  </div>
</div>

Upvotes: 2

Views: 1068

Answers (2)

DaniP
DaniP

Reputation: 38252

JQuery

With Jquery you can use more than one argument on the :not selector this way will be easy to exlude the .foo and child elements:

$('div:not(.foo, .foo *)')

Example Snippet

$('div:not(.foo, .foo *)').css('border-color','blue')
div {
  padding-left:20px;
  margin:5px;
  border:thin red solid;
}
.foo {
  background:rgba(0,0,0,.1)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
DIV1
  <div>
  DIV2
    <div>
    DIV4
      <div>DIV8</div>
      <div>DIV9</div>
    </div>
    <div class="foo">
    DIV5
      <div>DIV10</div>
      <div>DIV11</div>
    </div>
  </div>
  <div>
  DIV3
    <div>
    DIV6
      <div>DIV12</div>
      <div>DIV13</div>
    </div>
    <div class="foo">
    DIV7
      <div>DIV14</div>
      <div>DIV15</div>
    </div>
  </div>
</div>


But CSS doesn't allow that, refer to this answer.


CSS

On CSS you will need to target all divs that aren't .foo but also overwrite again the child elements of .foo:

div:not(.foo) {
  border-color:blue;
}
div.foo * {
  border-color:red;
}

Example Snippet

div {
  padding-left:20px;
  margin:5px;
  border:thin red solid;
}
.foo {
  background:rgba(0,0,0,.1)
}
div:not(.foo) {
  border-color:blue;
}
div.foo * {
  border-color:red;
}
<div>
DIV1
  <div>
  DIV2
    <div>
    DIV4
      <div>DIV8</div>
      <div>DIV9</div>
    </div>
    <div class="foo">
    DIV5
      <div>DIV10</div>
      <div>DIV11</div>
    </div>
  </div>
  <div>
  DIV3
    <div>
    DIV6
      <div>DIV12</div>
      <div>DIV13</div>
    </div>
    <div class="foo">
    DIV7
      <div>DIV14</div>
      <div>DIV15</div>
    </div>
  </div>
</div>

Upvotes: 6

Vaishal Patel
Vaishal Patel

Reputation: 439

Maybe use the :not selector ?

Something like

div:not(.foo)

Upvotes: 0

Related Questions