使用 querySelectorAll 检索直接子项

2022-08-30 01:07:08

我能够做到这一点:

<div id="myDiv">
   <div class="foo"></div>
</div>
myDiv = getElementById("myDiv");
myDiv.querySelectorAll("#myDiv > .foo");

也就是说,我可以成功检索具有类的元素的所有直接子级。myDiv.foo

问题是,我必须在选择器中包含 它困扰着我,因为我正在对元素运行查询(所以它显然是多余的)。#myDivmyDiv

我应该能够关闭,但是选择器不是合法的语法,因为它以.#myDiv>

有谁知道如何编写一个选择器,它只获取运行选择器的元素的直接子级?


答案 1

问得好。在它被问到的时候,一种普遍实现的方法来执行“组合器根查询”(如John Resig所称)并不存在。

现在引入了 :scope 伪类。它在Edge或IE的[pre-Chrominum]版本上不受支持,但Safari已经支持了几年。使用它,您的代码可能会变成:

let myDiv = getElementById("myDiv");
myDiv.querySelectorAll(":scope > .foo");

请注意,在某些情况下,您还可以跳过并使用其他良好的老式DOM API功能。例如,例如,您可以只写 ,而不是写。.querySelectorAllmyDiv.querySelectorAll(":scope > *")myDiv.children

否则,如果您还不能依赖,我想不出另一种方法来处理您的情况而不添加更多自定义过滤器逻辑(例如,找到谁),如果您尝试支持一个代码路径,并且如果您真的只想将任意选择器字符串作为输入,并将匹配列表作为输出,则显然不理想!但是,如果像我一样,你最终问了这个问题,仅仅是因为你陷入了思考“你所拥有的只是一把锤子”,不要忘记DOM还提供了各种其他工具。:scopemyDiv.getElementsByClassName("foo").parentNode === myDiv


答案 2

有谁知道如何编写一个选择器,它只获取运行选择器的元素的直接子级?

编写“根”到当前元素的选择器的正确方法是使用 :scope

var myDiv = getElementById("myDiv");
var fooEls = myDiv.querySelectorAll(":scope > .foo");

但是,浏览器支持有限,如果要使用它,则需要填充程序。我为此构建了scopedQuerySelectorShim