为什么.class: last-of-type 不像我期望的那样工作?

为什么这个不起作用? 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的引用,这会显示 div 中的最后一个 <p>,但这不是我想要的。

当然,我在任何时候都只能保留一个 .visible,但这是用于 Reval.js 演示的,我不能控制 JavaScript。

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

62959 次浏览

问题是 :last-of-type只匹配元素选择器。在您的示例中,您尝试匹配 class选择器。所以才不管用。

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

你的问题是,你正在阅读 :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>元素具有该类,而第三个元素没有。

这里有一个不同风格的演示来说明:

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 WITH 类中的最后一个元素。看得见?我不想为此使用 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 进行匹配,并且在避免所有 兄弟姐妹、后代和子选择器的使用实际上会使 页面在所有浏览器中的性能明显更好。

作为将来的参考,这将在 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>

瞄准倒数第二个标签。

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

这就是我解决非类问题的方法——不幸的是,这是一个 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>