84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
有没有一种方法可以选择每个满足(或不满足)任意选择器的第n个子元素?例如,我想选择每个奇数表格行,但在行的子集内:
table.myClass tr.row:nth-child(odd) { ... }
但是:nth-child()似乎只计算所有的tr元素,而不管它们是否是"row"类的,所以我最终得到的是一个偶数的"row"元素,而不是我要找的两个。同样的情况也发生在:nth-of-type()上。
:nth-child()
tr
:nth-of-type()
有人能解释一下为什么吗?
不是真的..
来自文档的引用
它是一个独立的选择器,不与类组合。在你的规则中,它只需要同时满足两个选择器,所以如果:nth-child(even)表格行也有.row类,它将显示。
:nth-child(even)
.row
这是一个非常常见的问题,它是由于对:nth-child(An+B)和:nth-of-type()的工作原理的误解而引起的。
:nth-child(An+B)
在选择器3级中,:nth-child()伪类计算的是在同一父元素下的所有同级元素中的位置,而不仅仅是匹配选择器的其余部分的同级元素。
同样地,:nth-of-type()伪类计算的是与其共享相同元素类型的同级元素,这在HTML中是指标签名,而不是选择器的其余部分。
这也意味着,如果同一父元素的所有子元素都是相同的元素类型,例如表格主体只有tr元素或列表元素只有li元素,那么:nth-child()和:nth-of-type()的行为将是相同的,即对于每个An+B的值,:nth-child(An+B)和:nth-of-type(An+B)将匹配相同的一组元素。
li
:nth-of-type(An+B)
事实上,在给定的复合选择器中的所有简单选择器,包括:nth-child()和:not()等伪类,都是独立工作的,而不是查看由选择器的其余部分匹配的子集元素。
:not()
这也意味着在每个单独的复合选择器中,简单选择器之间没有顺序的概念1,这意味着例如以下两个选择器是等价的:
table.myClass tr.row:nth-child(odd) table.myClass tr:nth-child(odd).row
翻译成英文,它们的意思都是:
(你会注意到我在这里使用了无序列表,只是为了强调这一点)
选择器4级试图通过允许:nth-child(An+B of S)2接受任意选择器参数S来纠正这个限制,这是由于选择器在复合选择器中独立操作,根据现有的选择器语法来决定。所以在你的情况下,它会是这样的:
:nth-child(An+B of S)
table.myClass tr:nth-child(odd of .row)
当然,作为一个全新的提议在全新的规范中,这可能要等到几年后才会实现。
与此同时,您将需要使用脚本来过滤元素并相应地应用样式或额外的类名。例如,以下是使用jQuery的常见解决方法(假设表格中只有一个包含tr元素的行组):
$('table.myClass').each(function() { // 注意,令人困惑的是,jQuery的过滤伪类是从0开始索引的,而CSS的:nth-child()是从1开始索引的 $('tr.row:even').addClass('odd'); });
对应的CSS为:
table.myClass tr.row.odd { ... }
如果您使用的是Selenium等自动化测试工具,或者使用BeautifulSoup等工具来解析HTML,许多这些工具都允许使用XPath作为替代方法:
//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]
使用不同技术的其他解决方案留给读者作为练习;这只是一个简短的、刻意的示例。
1如果指定了类型或通用选择器,则它必须放在第一位。然而,这并不改变选择器的基本工作原理;它只是一个语法上的怪癖。
2最初提出的是:nth-match(),然而,因为它仍然只计算相对于其同级元素,而不是与满足给定选择器的每个其他元素,所以自2014年以来,它已被重新用作现有的:nth-child()的扩展。
:nth-match()
不是真的..
来自文档的引用
它是一个独立的选择器,不与类组合。在你的规则中,它只需要同时满足两个选择器,所以如果
:nth-child(even)
表格行也有.row
类,它将显示。这是一个非常常见的问题,它是由于对
:nth-child(An+B)
和:nth-of-type()
的工作原理的误解而引起的。在选择器3级中,
:nth-child()
伪类计算的是在同一父元素下的所有同级元素中的位置,而不仅仅是匹配选择器的其余部分的同级元素。同样地,
:nth-of-type()
伪类计算的是与其共享相同元素类型的同级元素,这在HTML中是指标签名,而不是选择器的其余部分。这也意味着,如果同一父元素的所有子元素都是相同的元素类型,例如表格主体只有
tr
元素或列表元素只有li
元素,那么:nth-child()
和:nth-of-type()
的行为将是相同的,即对于每个An+B的值,:nth-child(An+B)
和:nth-of-type(An+B)
将匹配相同的一组元素。事实上,在给定的复合选择器中的所有简单选择器,包括
:nth-child()
和:not()
等伪类,都是独立工作的,而不是查看由选择器的其余部分匹配的子集元素。这也意味着在每个单独的复合选择器中,简单选择器之间没有顺序的概念1,这意味着例如以下两个选择器是等价的:
翻译成英文,它们的意思都是:
(你会注意到我在这里使用了无序列表,只是为了强调这一点)
选择器4级试图通过允许
:nth-child(An+B of S)
2接受任意选择器参数S来纠正这个限制,这是由于选择器在复合选择器中独立操作,根据现有的选择器语法来决定。所以在你的情况下,它会是这样的:当然,作为一个全新的提议在全新的规范中,这可能要等到几年后才会实现。
与此同时,您将需要使用脚本来过滤元素并相应地应用样式或额外的类名。例如,以下是使用jQuery的常见解决方法(假设表格中只有一个包含
tr
元素的行组):对应的CSS为:
如果您使用的是Selenium等自动化测试工具,或者使用BeautifulSoup等工具来解析HTML,许多这些工具都允许使用XPath作为替代方法:
使用不同技术的其他解决方案留给读者作为练习;这只是一个简短的、刻意的示例。
1如果指定了类型或通用选择器,则它必须放在第一位。然而,这并不改变选择器的基本工作原理;它只是一个语法上的怪癖。
2最初提出的是
:nth-match()
,然而,因为它仍然只计算相对于其同级元素,而不是与满足给定选择器的每个其他元素,所以自2014年以来,它已被重新用作现有的:nth-child()
的扩展。