Reputation: 1345
Assume I have html structure as
ul
li //this one
ul
li
li
li
li //this one
I don't want to get all li
's.
As I commented I just want to get first segment li's. How can I select them?
document.querySelectorAll("ul > li");
returns all li
's.
edit: actually this is just a snippet of the tree.
I can't modify the structure as adding class or id. I'm looking for an answer to get the list of first layer li
s
Upvotes: 3
Views: 28202
Reputation: 175
You can get the father's direct children. In this case, the "lis":
console.log(document.querySelector("ul").children)
<ul>
<li>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
<li>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
Upvotes: -2
Reputation: 2340
Try this it should do the trick :
$("ul > li").not("ul li ul li");
Also this should work in your case :
$("ul").first().children("li");
Upvotes: 1
Reputation: 22797
use :scope
console.log(source.querySelectorAll("ul:scope > li"));
<ul id="source">
<li>
this
<ul>
<li>not this</li>
<li>not this</li>
<li>not this</li>
</ul>
</li>
<li>
this
</li>
</ul>
Snapshot from Chrome console:
Upvotes: -1
Reputation: 943142
You need to select all the li items where the grandparent is not another list item.
:not(li) > * > li {}
This will only work if you don't have extra elements in the markup.
For example it would fail with:
<ul>
<li>
<div>
<ul>
<li>
A slower, but more reliable, approach would be to get all the list items and then filter out ones which had list item ancestors.
var lis = document.getElementsByTagName('li');
var lis_without_li_ancestors = [];
for (var i = 0; i < lis.length; i++) {
var element = lis[i];
if (!has_li_ancestor(element)) {
lis_without_li_ancestors.push(element);
}
}
console.log(lis_without_li_ancestors);
function has_li_ancestor(element) {
var parent = element.parentNode;
if (parent.tagName.toLowerCase() === "body") {
return false;
} else if (parent.tagName.toLowerCase() === "li") {
return true;
} else {
return has_li_ancestor(parent);
}
}
<ul>
<li>
<ul>
<li>...
</ul>
</ul>
Upvotes: 6
Reputation: 8423
In jQuery you can use this selector ul > li:not('ul > li > ul > li')
:
$("ul > li:not('ul > li > ul > li')").css("background", "green");
ul > li {
background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
First
<ul>
<li>
Second
<ul>
<li>Third</li>
</ul>
</li>
<li>Second</li>
<li>Second</li>
<li>Second</li>
</ul>
</li>
<li>First</li>
<li>First</li>
<li>First</li>
</ul>
Upvotes: 5
Reputation: 506
You could traverse the first ul's children and look for li's like the following.
function firstLis() {
var firstUl = document.querySelector('ul');
var list = [];
for(var i = 0; i < firstUl.children.length; i++) {
var element = firstUl.children[i];
if(element.tagName === 'LI')
list.push(element);
}
return list;
}
Upvotes: 0
Reputation: 5401
You can add an id
to that specific li
:
<li id="someID"></li>
then select it using:
var chosenOne = document.getElementById("someID");
Upvotes: 0