如果结构是可预测的并且是已知的:
container.querySelectorAll('div:not(#excludedElement) > p .MyClass');
如果结构 not 并且您可以添加类以避免 O(n^2):
container.querySelectorAll('#excludedElement .MyClass')
.forEach(element => element.classList.add('excluded'));
const notExcludedMyClassElements = container.querySelectorAll('.MyClass:not(.excluded)');
您可以选择所有
.MyClass
后代,然后 .filter
通过迭代当前项目是否具有 #excludedElement
祖先与 .closest
:
const classes = [...container.querySelectorAll('.MyClass')]
.filter(span => !span.closest('#excludedElement'));
for (const span of classes) {
span.style.backgroundColor = 'yellow';
}
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>
除非你事先知道
#container
的后代的确切结构类型,否则我认为没有一种优雅的方法可以用单个查询字符串来做到这一点; :not
只接受简单的选择器。
仅供参考,您不应该使用的一种愚蠢且重复的方法是使用查询字符串:
:scope > .MyClass,
:scope > *:not(#excludedElement) > .MyClass,
:scope > *:not(#excludedElement) > *:not(#excludedElement) > .MyClass
...
const selector = `
:scope > .MyClass,
:scope > *:not(#excludedElement) > .MyClass,
:scope > *:not(#excludedElement) > *:not(#excludedElement) > .MyClass
`;
const classes = container.querySelectorAll(selector);
for (const span of classes) {
span.style.backgroundColor = 'yellow';
}
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>
const Excludes = [...container.querySelectorAll('#excludedElement .MyClass')]
, noExcludes = [...container.querySelectorAll('.MyClass')].filter(el=>(!Excludes.includes(el)))
;
noExcludes.forEach(element => element.style.backgroundColor = 'lightgreen');
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>
.querySelectorAll()
中使用这个精确的选择器:
:not(#excludedElement) > p > .MyClass
工作示例:
const includedSpans = [... document.querySelectorAll(':not(#excludedElement) > p > .MyClass')];
includedSpans.forEach((includedSpan) => console.log(includedSpan.textContent));
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>