Reputation: 25928
I am trying to select all elements that are not inside the following divs <div class="manager"></div>
or <div class="release"></div>
.
So I have made my selector below however it is incorrectly selecting elements inside those above div's. Do you know how I can update my selector to ignore all elements inside <div class="manager"></div>
and <div class="release"></div>
?
$('*:not(.release, .manager) *').filter(function () {
return $(this).css('position') == 'fixed';
}).addClass('reset-pos');
Here is how my html is organised:
<body>
<div>
...
</div>
<!-- This element and all below should be ignored/not selected -->
<div class="manager">
...
</div>
<!-- This element and all below should be ignored/not selected -->
<div class="release">
...
</div>
</body>
Upvotes: 1
Views: 621
Reputation: 2973
You could use xPath and ancestor
. Working example:
<body>
<div class="outside"><div class="outside__child1"></div></div>
<!-- This element and all below should be ignored/not selected -->
<div class="manager"><div class="manager__child"></div></div>
<!-- This element and all below should be ignored/not selected -->
<div class="release"><div class="release__child"></div></div>
<script>
const path = "//div[not(contains(@class, 'manager')) and not(contains(@class, 'release')) and not(ancestor::div[contains(@class, 'manager') or contains(@class, 'release')])]"
const result = document.evaluate(path, document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null)
let node = result.iterateNext();
while(node) {
console.log(node);
node = result.iterateNext();
}
</script>
</body>
This prints out only div.outside
and its child as all others are ignored (I assume you wanted to ignore containers (div.manager
and div.release
also):
Upvotes: 0
Reputation: 73906
Instead of doing recursive traversing like:
$('*:not(.release, .manager) *')
You can simply do:
$('*:not(.release, .manager, .release *, .manager *)')
Working Demo:
(Note: I am using parent class for this demo, to exclude head and other tags as using *
includes everything)
$('.parent *:not(.release, .manager, .release *, .manager *)')
.addClass('reset-pos');
.reset-pos { border: 1px solid orange; padding: 5px; margin: 5px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div>
<p>Ouside manager & release</p>
</div>
<!-- This element and all below should be ignored/not selected -->
<div class="manager">
<p>Inside manager</p>
</div>
<!-- This element and all below should be ignored/not selected -->
<div class="release">
<p>Inside release</p>
</div>
</div>
Non-working Demo:
(This demo shows the issue with your selector, without any parent class)
$('*:not(.release, .manager) *').addClass('reset-pos');
.reset-pos { border: 1px solid orange; padding: 3px 8px; margin: 4px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p>Ouside manager & release</p>
</div>
<!-- This element and all below should be ignored/not selected -->
<div class="manager">
<p>Inside manager</p>
</div>
<!-- This element and all below should be ignored/not selected -->
<div class="release">
<p>Inside release</p>
</div>
Upvotes: 2
Reputation: 8044
You could use this selector
$('*:not(.manager):not(.release)') // this will get you the results you want
Also i believe this selector will bring results that you dont want like Head, title, meta elements, so i think the following is prorabbly better
$('body *:not(.manager):not(.release)')
Upvotes: 0