CSS选择器来排除所有的孩子在那里在任何级别的任何父母有一类(CSS selector to exc

2019-09-28 10:40发布

什么

我想创建一个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 --> 

:我已经想到了解决这个像迭代称为元素的所有孩子的其他方式“没有物质”,并添加类‘无料’所有,但毕竟是消耗资源的,我想解决这个问题从CSS选择器的角度来看,如果可能的。

谢谢

Answer 1:

找到的所有元素( all ),然后用元素no-material的元件上,或者它的父( no ),然后取出在那些从与第一,第二,以找到那些仍然( 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> 



Answer 2:

在现代浏览器,你可以使用CSS变量。

在根级别定义它,在你的类中重新定义它:

 :root { --mycolor: lightblue; } .container { --mycolor: lightgreen; } .test { background-color: var(--mycolor); } 
 <div class="test">BASE</div> <div class="container"> <div class="test">BASE</div> </div> 



文章来源: CSS selector to exclude all children where any parent at ANY LEVEL has a class