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

时间:2012-04-17 10:58:01

标签: javascript html css dom selectors-api

让我们假设您有一个包含嵌套子列表的列表。

<ul>
    <li></li>
    <li>
        <ul>
            <li></li>
            <li></li>
        </ul>
    </li>
    <li></li>
</ul>

并使用document.querySelectorAll()进行选择:

var ul = document.querySelectorAll("ul");

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

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

假设ul以某种方式缓存(否则我本可以直接完成ul > li。)

在jQuery中,这有效:

$("ul").find("> li");

但它不是原生querySelectorAll。任何解决方案?

3 个答案:

答案 0 :(得分:40)

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

ul.querySelectorAll(":scope > li");

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

答案 1 :(得分:13)

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

除此之外,querySelectorAll()不会使用>并从其当前上下文开始工作。但是,您可以使用lazd's answer(虽然检查浏览器兼容性)或任何这些变通办法(应该没有浏览器问题)让它工作......

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

jsFiddle

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

或者,您可以获取所有childNodes,然后过滤它们......

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

jsFiddle

答案 2 :(得分:0)

您需要迭代NodeList返回的document.querySelectorAll(),然后为该列表中的每个元素调用element.querySelectorAll()