什么是现代、简洁、快速的方法来测试节点是否有任何与给定选择器匹配的子节点?
“简洁”是指类似于 jQuery 或函数式风格,例如避免循环。我知道本地选择器越来越多地使用这种类型的东西,但没有跟上发展的步伐。如果跨浏览器尚不存在,那么我也想知道。
我原以为它会很简单,但使用 jQuery 搜索 Google 和 SO 会发现许多错误命中,或者在任何深度找到任意后代,而不仅仅是直接子代。在浏览器之间添加和标准化许多函数式方法之前,还有一些过时的问题。
最佳答案
一种选择是使用 direct child combinator, >
, 和 :scope
pseudo-class :
var children = parentElement.querySelectorAll(':scope > div');
var parentElement = document.querySelector('.container');
var children = parentElement.querySelectorAll(':scope > div');
for (var i = 0; i < children.length; i++) {
children[i].style.background = '#f00';
}
.level2 { background-color: #fff; }
<div class="container">
<span>Span</span>
<span>Span</span>
<div class="level1">Direct 'div'
<div class="level2">Nested 'div'</div>
</div>
<div class="level1">Direct 'div'
<div class="level2">Nested 'div'</div>
</div>
<div class="level1">Direct 'div'
<div class="level2">Nested 'div'</div>
</div>
</div>
注意 :scope
伪类仍然被认为是实验性的并且没有完整的浏览器支持。但尽管如此,它可能是最“现代”的解决方案(正如您所要求的)。
或者,您可以使用 .filter()
method并检查父元素的子元素是否匹配给定的选择器:
function getChildren(parent, selector) {
return Array.prototype.filter.call(parent.children, function(node) {
return node.matches(selector);
});
}
用法:
getChildren(parentElement, 'div'); // Direct children 'div' elements
function getChildren(parent, selector) {
return Array.prototype.filter.call(parent.children, function(node) {
return node.matches(selector);
});
}
var parentElement = document.querySelector('.container');
var children = getChildren(parentElement, 'div');
for (var i = 0; i < children.length; i++) {
children[i].style.background = '#f00';
}
.level2 { background-color: #fff; }
<div class="container">
<span>Span</span>
<span>Span</span>
<div class="level1">Direct 'div'
<div class="level2">Nested 'div'</div>
</div>
<div class="level1">Direct 'div'
<div class="level2">Nested 'div'</div>
</div>
<div class="level1">Direct 'div'
<div class="level2">Nested 'div'</div>
</div>
</div>
关于javascript - 现代、简洁、普通的 JS 检查节点是否有与选择器匹配的直接子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35027814/