【发布时间】:2017-06-12 21:52:39
【问题描述】:
什么
我正在尝试创建一个 CSS 选择器,它可以选择给定父级中的所有子级;但只要路径上的任何元素都有特定的类,就会排除它们。
上下文
我正在用 Javascript 创建一些物化类,它将一些元素替换为它们的材料版本。这在顶级应用程序上运行。每个用户都可以创建自己的应用程序,我想说的是,某组元素不应该经历这个过程。
示例
应该选择这个:
<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)
像这样 20-50 级(或更多?),但这不是很聪明。
现场版
您可以通过在 Javascript 中编辑 cssSelector 来测试您的选择器。
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 -->
注意:我已经想到了解决这个问题的其他方法,比如迭代一个名为“.no-material”的元素的所有子元素并将类“no-material”添加到所有元素中,但是这是资源消耗,如果可能的话,我想从 CSS 选择器的角度来解决这个问题。
谢谢
【问题讨论】:
-
无论如何,如果 CSS 选择过程没有任何索引(不确定其内部结构),您最终将以一种或另一种形式迭代所有元素。您可以通过
$("[class]")选择器(这是一个文字)迭代所有带有类的项目,然后如果它们有一个带有您要过滤的类的父项。 -
对于初学者来说,当你想匹配任何级别的孩子时,不要使用
>(直接孩子)。 -
这是已解决问题的副本:全局选择器与 :not(.class) 结合似乎不起作用stackoverflow.com/a/44497536/7973110
-
他们在 1 小时前问过,我在 3 小时前问过 :) 但是,是的,这似乎是同一个问题,以至于我看到相同的 span.no-material 里面有一个输入(这是一个结构很差)。 @JenniferGoncalves
-
@fvbuendia 对此表示赞同,并在另一个问题中对您的问题表示赞赏。
标签: javascript html css css-selectors