为什么.class:last-of-type无法正常工作?


72

为什么这不起作用?http://jsfiddle.net/84C5W/1/

p{
    display: none;
}
p.visible:last-of-type {
    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>

实际上,我所有的<p>元素都不可见。如果我.visible在选择器中删除对的引用,则确实会显示<p>div中的最后一个,但这不是我想要的。

当然,我只能一直保留一个.visible,但这只是一个reveal.js演示文稿,我无法控制JavaScript。

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

Answers:


112

您的问题是,您正在阅读:last-of-type并认为它可以用作:last-of-class选择器,而实际上它表示元素。不幸的是,没有用于类的最后一个实例的选择器。

W3C

:last-of-type伪类表示是它的类型的最后一个侧边的元件。

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

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

简而言之,您的选择器只会将其样式应用于<p> 同时具有该类的.visible。在您的标记中,只有前两个<p>元素具有该类。第三不。

这是一个不同样式的演示,以说明:

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>

按照您的最终目标,

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

最简单,最高效的方法是颠倒您尝试应用样式的方式。而不是尝试隐藏三个div中的两个,其中要隐藏的一个div有一个类,要隐藏的另一个div没有类,并且要显示的div与要隐藏的一个div具有相同的类其中有一个类(请参阅?这很令人困惑),请执行以下操作:

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

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装饰标记并在其上进行完全匹配,同时避免所有使用同级,后代和子选择器,实际上将使页面在所有浏览器中的性能明显提高。



7

定位倒数第二个标签。

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

3
我知道,但这不是我想要的。提示是元素可以是动态的,我不想绑定到CSS中的特定元素位置。
奥伊斯坦阿蒙森

1
好的,但是我的答案是给遇到类似困境的其他人的。不添加后续节点/标签。
Thisismint

5

供将来参考,将在CSS级别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>


尚无浏览器支持:/
Anant Gupta,

1
我知道,看来他们从拟议的规范中删除了这一点。
奥伊斯坦阿蒙森

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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.