CSS选择器排除任何级别的任何父级都有类的所有子级 [英] CSS selector to exclude all children where any parent at ANY LEVEL has a class
问题描述
我试图创建一个CSS选择器来选择给定父代中的所有子代;但只要路径上的任何元素具有某个类别,就排除它们。
上下文
我在Javascript中创建了一些materialization类,它将一些元素替换为它们的材质版本。这运行在顶级应用程序上。每个用户都可以创建自己的应用程序,并且我希望能够说一定数量的元素不应该经过这个过程。
示例 不应选择: 主要挑战是这个标签可以放在任何地方。示例: 或者它可以是: 已经过测试 我尝试了一些尝试。最好的情况是: 但是,它仍然带来一些误报。我可以通过添加很多级别来获得更准确的结果: 像20-50个级别(或更多? ),但这并不是很聪明。 直播版 您可以测试您的选择器通过编辑Javascript中的cssSelector。 <! - 不要编辑HTML,只需CSS选择器 - > < main style =display:none;> <! - 不可选 - > < div class =no-material> <输入名称=no-1> < / DIV> < DIV> < input name =no-2class =no-material> < / DIV> < DIV> < label class =no-material> <输入名称=no-3> < /标签> < / DIV> < DIV> < label class =no-material> <跨度> < input name =no-4> < /跨度> < /标签> < / DIV> < DIV> <标签> < span class =no-material> < input name =no-5> < /跨度> < /标签> < / DIV> <! - 可选 - > < DIV> < input name =yes-1> < / DIV> < DIV> < input name =yes-2> < / DIV> < DIV> <标签> < input name =yes-3> < /标签> < / DIV> < DIV> <标签> <跨度> <输入名称=是-4> < /跨度> < /标签> < / DIV> < DIV> <标签> <跨度> < input name =yes-5> < /跨度> < /标签> < / div>< / main><! - 不要编辑HTML,只是CSS选择器 - > 注意:我已经想到了解决这个问题的其他方法,比如迭代名为'.no-material'的元素的所有子元素,如果可能的话,将'no-material'添加到所有类中,但是这是耗费资源的问题,我想从CSS选择器的角度解决这个问题。 谢谢 找到所有元素( What I am trying to create a CSS selector which selects all children within a given parent; but excludes them as long as any element on the path has a certain class. Context I am creating some materialisation class in Javascript which replaces some elements into their material versions. This runs on a top-level app. Each user can create their own apps, and I want to be able to say that a certain group of elements should not go through this process. Example This should be selected: This should not be selected: The main challenge is that this label can be at any place. Example: Or it could be: Already tested I tried a few attempts. The best scenario was: However, it stills gives some false positives. I could get more accurate by adding a lot of levels like: And like that for 20-50 levels (or more?), but that's not very smart. Live version You can test your selectors by editing cssSelector in Javascript.
Note: I already have thought of other ways of solving this like iterating all the children of an element called '.no-material' and add the class 'no-material' to all, but that is resource consuming and I want to solve this from a CSS selector standpoint if possible. Thank you Find all the elements (
这篇关于CSS选择器排除任何级别的任何父级都有类的所有子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
$ b
$ b 应该选择:
< div>
< input />
< / div>
< div class =no-material>
< input />
< / div>
< main>
< section class =no-material>
< form>
< fieldset>
< input />
< / fieldset>
< / form>
< / section>
< / main>
< main>
<节>
< form class =no-material>
< fieldset>
< input />
< / fieldset>
< / form>
< / section>
< / main>
div:not(.no-material)>输入:不是(.no-material),div:不是(.no-material)*:不是(.no-material)输入:不是(.no-material)
pre>
div:not(.no-material)>输入:not(.no-material),
div:not(.no-material)> *:not(.no-material)>输入:not(.no-material),
div:not(.no-material)> *:not(.no-material)> *:not(.no-material)>输入:不是(.no-material)
$ b
all
),然后使用 no-material
对元素或其父元素( no
),然后从第一个元素中删除那些元素以找到那些元素(是
)。
const difference =(a,b)=> a.filter(elt => b.indexOf(elt)=== -1); const all = document.querySelectorAll(input); const no = document.querySelectorAll(。no-material input,input.no-material); const yes = difference([... all],[... no]); console.log(yes.map(elt => elt.name));
< main style =display:none;> <! - 不可选 - > < div class =no-material> <输入名称=no-1> < / DIV> < DIV> < input name =no-2class =no-material> < / DIV> < DIV> < label class =no-material> <输入名称=no-3> < /标签> < / DIV> < DIV> < label class =no-material> <跨度> < input name =no-4> < /跨度> < /标签> < / DIV> < DIV> <标签> < span class =no-material> < input name =no-5> < /跨度> < /标签> < / DIV> <! - 可选 - > < DIV> < input name =yes-1> < / DIV> < DIV> < input name =yes-2> < / DIV> < DIV> <标签> < input name =yes-3> < /标签> < / DIV> < DIV> <标签> <跨度> <输入名称=是-4> < /跨度> < /标签> < / DIV> < DIV> <标签> <跨度> < input name =yes-5> < /跨度> < /标签> < / div>< / main>
<div>
<input />
</div>
<div class="no-material">
<input />
</div>
<main>
<section class="no-material">
<form>
<fieldset>
<input />
</fieldset>
</form>
</section>
</main>
<main>
<section>
<form class="no-material">
<fieldset>
<input />
</fieldset>
</form>
</section>
</main>
div:not(.no-material) > input:not(.no-material), div:not(.no-material) *:not(.no-material) input:not(.no-material)
div:not(.no-material) > input:not(.no-material),
div:not(.no-material) > *:not(.no-material) > input:not(.no-material),
div:not(.no-material) > *:not(.no-material) > *:not(.no-material) > input:not(.no-material)
let cssSelector = [
// Independent selectors
'div:not(.no-material) > input:not(.no-material)',
'div:not(.no-material) *:not(.no-material) input:not(.no-material)'
].join(',');
// This will get elements and run their names. We should get yes1-5, but not no1-5.
let inputs = document.querySelectorAll(cssSelector);
for (let input of inputs) console.log(input.getAttribute('name'));
<!-- Do not edit HTML, just the CSS selector -->
<main style="display: none;">
<!-- Not selectable -->
<div class="no-material">
<input name="no-1">
</div>
<div>
<input name="no-2" class="no-material">
</div>
<div>
<label class="no-material">
<input name="no-3">
</label>
</div>
<div>
<label class="no-material">
<span>
<input name="no-4">
</span>
</label>
</div>
<div>
<label>
<span class="no-material">
<input name="no-5">
</span>
</label>
</div>
<!-- Selectable -->
<div>
<input name="yes-1">
</div>
<div>
<input name="yes-2">
</div>
<div>
<label>
<input name="yes-3">
</label>
</div>
<div>
<label>
<span>
<input name="yes-4">
</span>
</label>
</div>
<div>
<label>
<span>
<input name="yes-5">
</span>
</label>
</div>
</main>
<!-- Do not edit HTML, just the CSS selector -->
all
), then the elements with no-material
on the element or its parent (no
), then remove those in the second from those in the first to find those that remain (yes
).const difference = (a, b) => a.filter(elt => b.indexOf(elt) === -1);
const all = document.querySelectorAll("input");
const no = document.querySelectorAll(".no-material input, input.no-material");
const yes = difference([...all], [...no]);
console.log(yes.map(elt => elt.name));
<main style="display: none;">
<!-- Not selectable -->
<div class="no-material">
<input name="no-1">
</div>
<div>
<input name="no-2" class="no-material">
</div>
<div>
<label class="no-material">
<input name="no-3">
</label>
</div>
<div>
<label class="no-material">
<span>
<input name="no-4">
</span>
</label>
</div>
<div>
<label>
<span class="no-material">
<input name="no-5">
</span>
</label>
</div>
<!-- Selectable -->
<div>
<input name="yes-1">
</div>
<div>
<input name="yes-2">
</div>
<div>
<label>
<input name="yes-3">
</label>
</div>
<div>
<label>
<span>
<input name="yes-4">
</span>
</label>
</div>
<div>
<label>
<span>
<input name="yes-5">
</span>
</label>
</div>
</main>