Reputation: 19
Below is label.
<label style="vertical-align: middle; cursor: pointer;">Terrain</label>
It is nested in following structure (see label at the end):
<div class="event-section">
<div class="googlemaps">
<div id="googleMap6512">
<div>
<div class="gm-style">
<div class="gmnoprint">
<div class="gm-style-mtc">
<div>
<div>
<label>...
Problem:
I want to exclude this label in my Javascript together with the label from another div.widget_small
and I tried this here:
var arrInp = document.querySelectorAll("label:not(.googlemaps):not(.widget_small)");
This did not work. I think I picked the wrong selector or… ?
Upvotes: 0
Views: 2066
Reputation: 253396
A relatively simple approach, using JavaScript, is the following:
// converting the resulting iterable into an Array:
Array.from(
// using document.querySelectorAll() to retrieve
// a NodeList of all <label> elements in the
// document:
document.querySelectorAll('label')
// filtering that Array of <label> elements with
// Array.prototype.filter():
).filter(
// using an Arrow function to filter the Array elements:
// 'el' is a reference to the current Array element,
// here we find the closest ancestor element which
// matches the supplied selector; coupled with the NOT
// (!) operator to invert the 'truthiness' of the result,
// therefore if closest() returns null (no element was
// found) we convert that to true; thereby keeping the
// Array elements with no matching ancestors:
(el) => !el.closest('.demo, .test')
// iterating over the resulting Array using
// Array.prototype.forEach():
).forEach(
// with another Arrow function, here we use the
// Element.classList API to add a class, in this
// instance just to demonstrate which element(s)
// were found:
(label) => label.classList.add('orange')
);
.orange {
color: #f90;
}
<div class="demo"><label for="">label 1<input type="text"></label></div>
<div class="test"><label for="">label 1<input type="text"></label></div>
<label for="">label 1<input type="text"></label>
References:
Array.from()
.Array.prototype.filter()
.Arrow.prototype.forEach()
.Element.closest()
.!
) operator.Upvotes: 0
Reputation: 123
In your code:
var arrInp = document.querySelectorAll("label:not(.googlemaps):not(.widget_small)");
the selector part gets all label
which haven't the classes .googlemaps
or .widget_small
.
Please see reference to the :not selector: MDN web docs :not()
To achieve a solution consider @Quentin's statement.
Update
Maybe sth. like this is what you need, like @ChrisLi mentioned above?
var arrInp = document.querySelectorAll(".event-section > div:not(.googlemaps):not(.widget_small) label");
Upvotes: 0
Reputation: 943979
Classes are not inherited.
The label
isn't a member of googlemaps
or widget_small
so label:not(.googlemaps):not(.widget_small)
does match it.
You need to select a label where none of the ancestors are members of those classes.
There is no way to express that in a selector, so you need to select all label
elements and then loop over them filtering out those which have ancestors with either of those classes (which you can determine by recursively looping over .parentNode
until you find one which matches .googlemaps, .widget_small
(fail) or body
(success).
Alternatively, you can might be able to be very precise about which ancestors the element has:
:not(.googlemaps) > * > * > * > * > * > * > * > label
… but that is probably more trouble to maintain than it is worth.
Upvotes: 2