有没有办法选择匹配(或不匹配)任意选择器的第n个 child ?例如,我要选择每个奇数表行,但要在行的子集内:

table.myClass tr.row:nth-child(odd) {
  ...
}

<table class="myClass">
  <tr>
    <td>Row
  <tr class="row"> <!-- I want this -->
    <td>Row
  <tr class="row">
    <td>Row
  <tr class="row"> <!-- And this -->
    <td>Row
</table>

但是:nth-child()似乎只是计算所有tr元素,而不管它们是否属于“row”类,因此我最终得到一个偶数“row”元素,而不是我要查找的两个元素。 :nth-of-type()也发生同样的事情。

有人可以解释为什么吗?

最佳答案

这是由于对:nth-child():nth-of-type()的工作方式存在误解而引起的非常普遍的问题。不幸的是,目前还没有基于选择器的解决方案,因为选择器尚未提供匹配第n个子对象的方法,该子对象基于诸如奇数,偶数或an+ba != 1的任何b != 0等模式匹配任意选择器。这不仅限于类选择器,还包括属性选择器,取反和简单选择器的更复杂组合。
:nth-child() pseudo-class在同一个父对象的所有同胞中计数元素。它不只计算与选择器其余部分匹配的 sibling 。同样, :nth-of-type() pseudo-class会计算共享相同元素类型的 sibling ,这是指HTML中的标签名称,而不是选择器的其余部分。
这也意味着,如果同一父级的所有子级都具有相同的元素类型,例如,在表体中唯一的子级是tr元素或列表元素的唯一子级是li元素,则:nth-child():nth-of-type()将行为相同,即对于an+b的每个值,:nth-child(an+b):nth-of-type(an+b)将匹配同一组元素。
实际上,给定复合选择器中的所有简单选择器(包括诸如:nth-child():not()的伪类)都彼此独立工作,而不是查看与选择器其余部分匹配的元素子集。
这也意味着在每个单独的复合选择器 1中的简单选择器之间没有顺序的概念,这意味着例如以下两个选择器是等效的:

table.myClass tr.row:nth-child(odd)
table.myClass tr:nth-child(odd).row
翻译成英文,它们的意思是:

(您会注意到我在这里使用的是无序列表,只是为了将要点指向家)
因为目前还没有纯CSS解决方案,所以您必须使用脚本来过滤元素并相应地应用样式或额外的类名称。例如,以下是使用jQuery的常见解决方法(假设表中只有一个行组填充了tr元素):
$('table.myClass').each(function() {
  // Note that, confusingly, jQuery's filter pseudos are 0-indexed
  // while CSS :nth-child() is 1-indexed
  $('tr.row:even').addClass('odd');
});
使用相应的CSS:
table.myClass tr.row.odd {
  ...
}
如果您使用诸如Selenium之类的自动化测试工具,或者使用诸如lxml之类的工具来处理HTML,则其中许多工具都可以将XPath用作替代方法:
//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]
其他使用不同技术的解决方案留给读者练习。这只是一个简短的,人为的示例。

对于它的值(value),有人建议将an extension to the :nth-child() notation添加到选择器级别4,以特定目的选择每n个与给定选择器匹配的子对象。2
同样,由于选择器如何按照现有选择器语法规定的顺序彼此独立地操作,因此将筛选器用来匹配的选择器作为:nth-child()的参数提供。因此,在您的情况下,它将如下所示:
table.myClass tr:nth-child(odd of .row)
(精明的读者会立即注意到,应该将其改为:nth-child(odd of tr.row),因为简单的选择器tr:nth-child()也彼此独立运行。这是接受选择器(一 jar 蠕虫)的功能性伪类的问题之一我宁愿不要在这个答案的中间开口,而是假设大多数站点除了tr元素外,没有其他元素作为表主体中的彼此的 sibling ,这将使任何一个选项功能上等效。)
当然,作为全新规范中的全新提案,可能要等到几年后才能实现。同时,您必须坚持使用脚本,如上所述。

1如果指定类型或通用选择器,则必须排在最前面。但是,这不会改变选择器的基本工作方式。只是语法上的怪异而已。
2最初被提议为:nth-match(),但是因为它仍然仅计数与其同级相对的元素,而不是与匹配给定选择器的其他所有元素相对的元素,因此自2014年起,它被重新用作现有:nth-child()的扩展。

10-05 20:56
查看更多