为什么 .class:last-of-type 不能按我的预期工作?

问题描述 投票:0回答:6
html css css-selectors
6个回答
156
投票

您的问题是您正在阅读

:last-of-type
并认为它作为
:last-of-class
选择器工作,而实际上它具体意味着 仅元素。不幸的是,类的最后一个实例没有选择器。

来自 W3C

:last-of-type
伪类表示一个元素,该元素是其类型的最后一个同级元素。

您有

p.visible:last-of-type
作为选择器,它执行以下操作:

  1. 查看 HTML 中每个包含元素中的每个元素列表(例如 1 个或多个元素;没有兄弟姐妹的子元素仍可以应用
    :last-of-type
  2. 找到列表中的最后一个元素
  3. 检查它是否是一个
    <p>
    元素
  4. 检查它是否有
    .visible
    类。

简而言之,您的选择器只会将其样式应用于也具有

<p>.visible
 
。在您的标记中,只有前两个
<p>
元素具有该类;第三个没有。

这里有不同风格的demo来说明:

p:last-of-type {
  /* this will be applied in the third paragraph because the pseudo-selector checks for nodes only */
  color: green;
}
p.visible:last-of-type {
  /* this does not get applied, because you are using the pseudo-selector with a specific class in addition to the node type. */
  color: red;
}
<p class="visible">First paragraph.</p>
<p class="visible">Second paragraph.</p>
<p>Third paragraph.</p>

根据您的最终目标,

如何选择 div 中带有 .visible 类的最后一个元素?我不想为此使用 JavaScript。

最简单且最高效的方法是反转您尝试应用样式的方式;而不是尝试隐藏三个 div 中的两个,其中要隐藏的 div 之一具有类,而要隐藏的另一个 div 没有类,并且要显示的 div 与要隐藏的 div 共享相同的类其中 also 有一个类(看到了吗?这很令人困惑),请执行以下操作:

  • 仅将类添加到较小的元素(或元素组)。
  • 将元素的默认样式设置为您不希望类实现的样式。
  • 将类的样式设置为您想要实现的效果。

p {
    display: none;
}
.visible {
    display: block;
}
<div>
    <p>This should be hidden</p>
    <p class="visible">This should be displayed</p>
    <p>This should be hidden</p>
</div>

正如您从这个演示中看到的,不仅您的 HTML 和 CSS 更简单,而且还具有仅使用类选择器而不是

*-of-type
伪选择器的好处,这将使页面加载速度更快(查看更多就在下面)。

为什么没有后面跟着父选择器 通过动态更改页面上的一个类名,可能会降低许多网页的速度。

Dave Hyatt 在 2008 年致力于 WebKit 实现时,提到了避免这些实现的一些原因

使用父选择器,很容易意外导致 文档范围内的卑躬屈膝。人们可能并且将会滥用这个选择器。 支持它就是给人们一大堆绳子来吊死自己 与.

CSS3 选择器的可悲事实是它们真的不应该 如果您关心页面性能,则完全可以使用。装饰你的标记 与类和 ID 并纯粹匹配这些,同时避免所有 使用兄弟、后代和子选择器实际上会产生 页面在所有浏览器中的表现明显更好。


12
投票

问题是

:last-of-type
只匹配元素选择器。在您的示例中,您尝试匹配
class
选择器。这就是为什么它不起作用。

示例:http://dabblet.com/gist/4144885


11
投票

定位倒数第二个标签。

.visible:nth-last-of-type(2) {}

7
投票

为了将来参考,这将在 CSS level 4 中介绍:https://www.w3.org/TR/selectors4/#the-nth-last-match-pseudo

在撰写本文时,浏览器支持还不存在:http://css4-selectors.com/selector/css4/structural-pseudo-class/

准备好后,这应该就是解决方案:

p {
  display : none;
}
p.visible:nth-last-match(0) {
  display : block;
}
<div>
  <p class="visible">This should be hidden</p>
  <p class="visible">This should be displayed</p>
  <p class="">This should be hidden</p>
</div>


0
投票

这是我解决非类问题的方法 - 不幸的是,这是一个 Javascript 解决方案:

function lastOfType(className){
            var allElemsOfType = document.getElementsByClassName(className);
            if (!allElemsOfType || !allElemsOfType.length) return null;
            else return allElemsOfType[allElemsOfType.length - 1];
    }

lastOfType('visible').style.display = 'block'
.visible {
  display: none;
}

p {
  display: none;
}
<p class='visible'>1</p>
<p class='visible'>2</p>
<p>3</p>


0
投票

由于 :has() 在本文发布时现已可用,因此这实际上是可能的,尽管性能成本未知。

您可以通过检查某个元素是否没有任何匹配的后续兄弟元素来做到这一点

p{
  display: none;
}
p.visible:not(:has(~.visible)) {
  display: block;
}
© www.soinside.com 2019 - 2024. All rights reserved.