在两个元素之间选择特定元素

时间:2020-07-31 11:58:02

标签: javascript css css-selectors

我给出了一些相当令人讨厌的HTML,并且想要遍历给定标题下的所有列表元素。不幸的是,我想略过一些评论。

<header><h2>A</h2></header>
<ul class="list">...</ul>
<header><h2>C</h2></header>
<p>Some comment</p>
<ul class="list">...</ul>
<p>Another comment</p>
<ul class="list">...</ul>
<header><h2>B</h2></header>
<p>Some comment</p>
<ul class="list">...</ul>

我尝试过document.querySelectorAll('h2 ~ .list:not(h2)'),但这什么也没返回。

因此,理想情况下,我将遍历每个标头,并为每个标头检索list,类似

const headers = document.querySelectorAll('h2');
for(let i = 0; i < headers.length; ++i)
{
  // Somehow get an Array of `list` elements between h2 i and i+1
}

2 个答案:

答案 0 :(得分:1)

如果只需要ul元素,则可以将选择器简化为'header ~ .list'。这是因为h2元素是header的子元素,并且没有兄弟姐妹,因此常规兄弟姐妹选择器“〜”没有任何匹配。

const lists = document.querySelectorAll('header ~ .list');

console.log(lists.length);
<header><h2>A</h2></header>
<ul class="list">...</ul>
<header><h2>C</h2></header>
<p>Some comment</p>
<ul class="list">...</ul>
<p>Another comment</p>
<ul class="list">...</ul>
<header><h2>B</h2></header>
<p>Some comment</p>
<ul class="list">...</ul>

答案 1 :(得分:0)

假设您想同时使用header和与之相关的.list,一次选择不会帮您,您将需要遍历。 (如果您只需要.list,请参阅chazsolo's answer。)

  1. 选择header元素。
  2. 遍历他们
    1. 在“此” nextElementSibling处理您发现的任何header之后,遍历兄弟姐妹(ul),直到第一个header为止

大致:

// Ideally, if you can narrow down this initial select, that would be good
const headers = document.querySelectorAll("header");
for (const header of headers) { // *** See note
    let list = header.nextElementSibling;
    while (list && list.tagName !== "HEADER") {
        if (list.tagName === "UL") {
            console.log("Found: " + list.id);
        }
        list = list.nextElementSibling;
    }
}

实时示例:

// Ideally, if you can narrow down this initial select, that would be good
const headers = document.querySelectorAll("header");
for (const header of headers) { // *** See notes
    let list = header.nextElementSibling;
    while (list && list.tagName !== "HEADER") {
        if (list.tagName === "UL") {
            console.log("Found: " + list.id);
        }
        list = list.nextElementSibling;
    }
}
<!-- Added IDs just to make showing them easier -->
<header><h2>A</h2></header>
<ul class="list" id="list1">...</ul>
<header><h2>C</h2></header>
<p>Some comment</p>
<ul class="list" id="list2">...</ul>
<p>Another comment</p>
<ul class="list" id="list3">...</ul>
<header><h2>B</h2></header>
<p>Some comment</p>
<ul class="list" id="list4">...</ul>


关于for (const header of headers)的说明:这取决于NodeList中的querySelectorAll是可迭代的。它被指定为可迭代的,并且在现代浏览器中是可迭代的,但是稍旧的(且已过时的)浏览器可能具有NodeList而无法迭代。在这种情况下,您可能可以使用forEach。但是过时的浏览器甚至没有。您可能可以同时填充forEach或可迭代性,或同时填充两者,请参见my answer here了解详细信息。否则,请使用老式的for循环。 :-)

相关问题