【问题标题】:Child selector using `querySelectorAll` on a DOM collection在 DOM 集合上使用 `querySelectorAll` 的子选择器
【发布时间】:2012-04-28 17:08:33
【问题描述】:

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

<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 &gt; li)。

在 jQuery 中这有效:

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

但它不在本机 querySelectorAll 中。有什么解决办法吗?

【问题讨论】:

  • 那个选择器真的没有意义。使用 jQuery,您将使用 .children("li") 而不是 .find("&gt; li")。实际上,我很惊讶这完全有效。
  • @MДΓΓБДLL .find('&gt; li ul span') 很有用,但不像 OP 的示例中那样单独使用。
  • @MДΓΓБДLL 这个例子有点做作,但它肯定有一个真实的用例:)

标签: javascript html css dom selectors-api


【解决方案1】:

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

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

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

【讨论】:

  • 很高兴看到这个存在! :)
  • 记住browser compatibility:Chrome:是,FF:32,IE:否,Opera:否,Safari:7
  • 除了@Web_Designer 所说的,直到今天它仍然在 Microsoft Edge 中也不受支持。尝试在 querySelectorAll 中使用“范围”会出现语法错误。对于“你不需要 jQuery”阵营来说就这么多。
【解决方案2】:

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

除此之外,querySelectorAll() 不会采用 &gt; 并在其当前上下文中工作。但是,您可以使用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.

【讨论】:

  • 是的,这似乎是一个可行的解决方案。太糟糕了,它需要三行代码才能在一个字符中完成:) 请注意,filter() 将不起作用,因为ul 是一个 NodeList,因此您需要先执行 Array.prototype.slice.call
  • @Husky 您可以随时将其作为函数添加到Element.prototype :)
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2016-02-10
    • 2022-07-05
    • 1970-01-01
    • 2022-06-15
    • 2018-11-04
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多