在DOM集合上使用`querySelectorAll`的子选择器

Hus*_*sky 24 html javascript css dom selectors-api

让我们假设您有一个嵌套子列表的列表.

<ul>
    <li></li>
    <li>
        <ul>
            <li></li>
            <li></li>
        </ul>
    </li>
    <li></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

并用于document.querySelectorAll()做出选择:

var ul = document.querySelectorAll("ul");
Run Code Online (Sandbox Code Playgroud)

我如何使用该ul集合来获取直接的子元素?

ul.querySelectorAll("> li"); 
// Gives 'Error: An invalid or illegal string was specified'
Run Code Online (Sandbox Code Playgroud)

让我们假定ul以某种方式缓存(否则我可以ul > li直接完成).

在jQuery中,这有效:

$("ul").find("> li");
Run Code Online (Sandbox Code Playgroud)

但它不是原生的querySelectorAll.有解决方案吗

laz*_*azd 40

编写一个"根"到当前元素的选择器的正确方法是使用:scope.

ul.querySelectorAll(":scope > li");
Run Code Online (Sandbox Code Playgroud)

请在此处查看我的答案,以获得解释和强大的跨浏览器解决方案:https://stackoverflow.com/a/21126966/1170723

  • 请记住[浏览器兼容性](https://developer.mozilla.org/en-US/docs/Web/CSS/%3ascope#Browser_compatibility):Chrome:是,FF:32,IE:不,歌剧:否,Safari:7 (7认同)
  • 很高兴看到这存在!:) (3认同)

ale*_*lex 13

因为ul返回的是NodeList,所以它不会像jQuery集合那样隐式循环其内容.您需要使用ul[0].querySelectorAll()或更好地选择ulwith querySelector().

除此之外,querySelectorAll()不会>从当前的背景下开始工作.但是,您可以使用lazd的答案(虽然检查浏览器兼容性)或任何这些变通方法(应该没有浏览器问题)让它工作......

[].filter.call(ul.querySelectorAll("li"), function(element){
     return element.parentNode == ul;
}); 
Run Code Online (Sandbox Code Playgroud)

jsFiddle.

这将选择li作为您的后代的所有元素,ul然后删除不是直接后代的元素.

或者,你可以得到所有childNodes,然后过滤它们......

[].filter.call(ul.childNodes, function(node) {
    return node.nodeType == 1 && node.tagName.toLowerCase() == 'li';
});
Run Code Online (Sandbox Code Playgroud)

jsFiddle.