Let's presume you got a list with nested child lists.
<ul>
<li></li>
<li>
<ul>
<li></li>
<li></li>
</ul>
</li>
<li></li>
</ul>
And use document.querySelectorAll()
to make a selection:
var ul = document.querySelectorAll("ul");
How can i use the ul
collection to get the direct child elements?
ul.querySelectorAll("> li");
// Gives 'Error: An invalid or illegal string was specified'
Let's presume ul
is cached somehow (otherwise i could have done ul > li
directly).
In jQuery this works:
$("ul").find("> li");
But it doesn't in native querySelectorAll
. Any solutions?
The correct way to write a selector that is "rooted" to the current element is to use :scope
.
ul.querySelectorAll(":scope > li");
See my answer here for an explanation and a robust, cross-browser solution: https://stackoverflow.com/a/21126966/1170723
Because the ul
returned is a NodeList, it doesn't implicitly loop over its contents like a jQuery collection. You'd need to use ul[0].querySelectorAll()
or better still select the ul
with querySelector()
.
Besides that, querySelectorAll()
won't take a >
and work from its current context. However, you can get it to work using lazd's answer (though check the browser compatibility), or any of these workarounds (which should have no browser issues)...
[].filter.call(ul.querySelectorAll("li"), function(element){
return element.parentNode == ul;
});
jsFiddle.
This will select all li
elements that are descendants of your ul
, and then remove the ones which are not direct descendants.
Alternatively, you could get all childNodes
and then filter them...
[].filter.call(ul.childNodes, function(node) {
return node.nodeType == 1 && node.tagName.toLowerCase() == 'li';
});
jsFiddle.
You need to iterate over the NodeList
returned by document.querySelectorAll()
and then call element.querySelectorAll()
for each element in that list.