-
Notifications
You must be signed in to change notification settings - Fork 1
如何选择某类的最后一个元素? #99
Copy link
Copy link
Open
Description
在牛客网上偶然看到这样一个面试题:
有很多li标签且顺序不固定,怎么把最后一个class为b的li改为红色:
<ul> <li class="a" /> <li class="b" /> <li class="b" /> <li class="a" /> ... </ul>
刚看到这道题,第一想法是通过js来解决:
const nodes = document.querySelectorAll('ul > .b');
const node = nodes[nodes.length - 1];
node.style.backgroundColor = 'red';这样虽然可以解决,但是看起来比较冗余。
可不可以通过css伪类来解决呢?
:last-child
document.querySelector('ul > .b:last-child')`; // null找不到元素。
:last-of-type
document.querySelector('ul > .b:last-of-type')`; // null也找不到元素。
刚开始有点不解,翻了一下标准文档,才发现,.b:last-of-type的工作原理是这样的:
- 通过
.b找到对应元素 - 确定元素的标签类型(上面例子是
li) - 找到最后一个
li.b元素。 - 如果它是父元素下的最后一个同类型子元素,则命中;否则不命中。
上面的例子中,由于都是li元素,所以通过.b选出来的最后一个元素,并非是父元素下最后一个li标签,所以找不到元素。
核心问题在于元素的标签类型是否相同。
如果是不同的元素类型, 则结果不一样。
案例1:
<div>
<div>这是一个干扰段落。</div>
<p class="p">这是第一个段落。</p>
<p class="p">这是第二个段落。</p>
<p class="p">这是第三个段落。</p>
<div>这是一个干扰段落。</div>
</div>
<script>
document.querySelector('div > .p:last-of-type')`; // <p class="p">这是第三个段落。</p>
</script>先找到第一个.p元素,然后确定标签类型是p,所以最后一个同类型的.p元素就是“第三个段落”。
案例2:
<div>
<div>这是一个干扰段落。</div>
<p class="p">这是第一个段落。</p>
<p class="p">这是第二个段落。</p>
<p class="p">这是第三个段落。</p>
<div class="p">这是一个干扰段落。</div>
</div>
<script>
document.querySelector('div > .p:last-of-type')`; // <p class="p">这是第三个段落。</p>
</script>最后一个div的class虽然也是.p,但是由于不是p标签,所以命中的是“第三段落”的p标签。
nth-last-child
最后只能通过nth-last-child(2)来解决了。
document.querySelector('ul .b:nth-last-child(2)'); // <li class="b">b</li>参考文章
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels