it-swarm.com.ru

Дочерний селектор, использующий `querySelectorAll` в коллекции DOM

Предположим, у вас есть список с вложенными дочерними списками.

<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. Какие-либо решения?

23
Husky

Правильный способ написать селектор, который «укоренен» в текущем элементе, это использовать :scope .

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

Смотрите мой ответ здесь для объяснения и надежного, кросс-браузерного решения: https://stackoverflow.com/a/21126966/1170723

39
lazd

Поскольку возвращаемый ul является NodeList, он неявно циклически перебирает свое содержимое, как коллекция jQuery. Вам нужно будет использовать ul[0].querySelectorAll() или, что еще лучше, выбрать ul с querySelector().

Кроме того, querySelectorAll() не будет принимать > и работать в его текущем контексте. Тем не менее, вы можете заставить его работать, используя ответ lazd (хотя проверьте совместимость браузера), или любой из этих обходных путей (которые не должны иметь проблем с браузером) ...

[].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 .

13
alex

Вам нужно перебрать NodeList, возвращенную document.querySelectorAll(), а затем вызвать element.querySelectorAll() для каждого элемента в этом списке.

0
Alnitak