我可以结合:nth-​​child()或:nth-​​of-type()与任意选择器? [英] Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?

查看:194
本文介绍了我可以结合:nth-​​child()或:nth-​​of-type()与任意选择器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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


b $ b

 < table class =myClass> 
< tr>
< td> Row
< tr class =row> <! - 我想要 - >
< 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 code>和:nth-​​of-type()工作。不幸的是,目前还没有基于选择器的解决方案,因为Selectors没有提供一种方法来匹配匹配基于模式的任意选择器的第n个孩子,例如奇数,偶数或任何 a + b 其中 a!= 1 b!= 0 。这不仅仅是类选择器,属性选择器,否定和更复杂的简单选择器组合。



:nth-​​child() em> all 的兄弟姐妹。它不会只计算与选择器其余部分匹配的兄弟。同样, :nth-​​of-type () pseudo-class 计算共享相同元素类型的兄弟姐妹,它引用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

翻译为英文,它们都是:


选择任何 tr 匹配所有以下独立条件:




  • 它是父级的奇数子级;

  • 它有类row;和

  • 它是具有类myClass的元素的后代。


(您会注意到我在这里使用了无序列表, / p>

因为目前没有纯CSS解决方案,您必须使用脚本来过滤元素,并相应地应用样式或额外的类名。例如,以下是使用jQuery的常见解决方法(假设表中只有一个填充了 tr 元素的行组):

  $('table.myClass')每个(function(){
//注意,混淆的是,jQuery的过滤器伪元素为0索引
// while CSS:nth-​​child()is 1-indexed
$('tr.row:even')。addClass('odd');
}

使用相应的CSS:

  table.myClass tr.row.odd {
...
}

如果您使用自动测试工具(如Selenium)或使用诸如lxml之类的工具处理HTML,许多这些工具允许XPath作为替代:



< pre(concat('',@class,''),'myClass')] // tr [contains(concat(' ',@class,''),'row')] [position()mod 2)= 1]

使用不同技术的其他解决方案留给读者作为练习;






有价值的建议是 :nth-​​child()的扩展名,


$

b $ b

过滤匹配的选择器作为参数提供给:nth-​​child(),这又是由于选择器如何彼此独立操作由现有选择器语法指定的序列。所以在你的case,它看起来像这样:

  table.myClass tr:nth-​​child精明的读者会立即注意到,这应该是:nth-​​b $ b  



<因为简单选择器 tr :nth-​​child()操作彼此独立,这是接受选择器的功能伪类的问题之一,我可能不想在这个答案中打开一个蠕虫,而是我要去假设大多数站点不会有任何其他元素,而不是 tr 元素作为表体中彼此的同级,这将使选项在功能上等效。)



当然,作为一个全新的规范中的一个全新的提案,这可能不会看到实现,直到几年下来。






1

sup> 如果指定类型或通用选择器,它必须先到达。然而,这并不改变选择器的基本工作方式;



2 这是最初提出的: nth-match(),但是因为它仍然计算一个元素只相对于其兄弟姐妹,而不是每个其他元素匹配给定的选择器,它自2014年以来被重用为一个扩展改为使用现有的:nth-​​child()


Is there a way to select every nth child that matches (or does not match) an arbitrary selector? For example, I want to select every odd table row, but within a subset of the rows:

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>

But :nth-child() just seems to count all the tr elements regardless of whether or not they're of the "row" class, so I end up with the one even "row" element instead of the two I'm looking for. The same thing happens with :nth-of-type().

Can someone explain why?

解决方案

This is a very common problem that arises due to a misunderstanding of how :nth-child() and :nth-of-type() work. Unfortunately, there is currently no selector-based solution as yet because Selectors does not provide a way to match the nth child that matches an arbitrary selector based on a pattern such as odd-numbered, even-numbered or any an+b where a != 1 and b != 0. This extends beyond just class selectors, to attribute selectors, negations, and more complex combinations of simple selectors.

The :nth-child() pseudo-class counts elements among all of their siblings under the same parent. It does not count only the siblings that match the rest of the selector. Similarly, the :nth-of-type() pseudo-class counts siblings sharing the same element type, which refers to the tag name in HTML, and not the rest of the selector.

This also means that if all the children of the same parent are of the same element type, for example in the case of a table body whose only children are tr elements or a list element whose only children are li elements, then :nth-child() and :nth-of-type() will behave identically, i.e. for every value of an+b, :nth-child(an+b) and :nth-of-type(an+b) will match the same set of elements.

In fact, all simple selectors in a given compound selector, including pseudo-classes such as :nth-child() and :not(), work independently of one another, rather than looking at the subset of elements that are matched by the rest of the selector.

This also implies that there is no notion of order among simple selectors within each individual compound selector1, which means for example the following two selectors are equivalent:

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

Translated to English, they both mean:

Select any tr element that matches all of the following independent conditions:

  • it is an odd-numbered child of its parent;
  • it has the class "row"; and
  • it is a descendant of a table element that has the class "myClass".

(you'll notice my use of an unordered list here, just to drive the point home)

Because there is currently no pure CSS solution, you'll have to use a script to filter elements and apply styles or extra class names accordingly. For example, the following is a common workaround using jQuery (assuming there is only one row group populated with tr elements within the table):

$('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');
});

With the corresponding CSS:

table.myClass tr.row.odd {
  ...
}

If you're using automated testing tools such as Selenium or processing HTML with tools like lxml, many of these tools allow XPath as an alternative:

//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]

Other solutions using different technologies are left as an exercise to the reader; this is just a brief, contrived example for illustration.


For what it's worth, there is a proposal for an extension to the :nth-child() notation to be added to Selectors level 4 for the specific purpose of selecting every nth child matching a given selector.2

The selector by which to filter matches is provided as an argument to :nth-child(), again due to how selectors operate independently of one another in a sequence as dictated by the existing selector syntax. So in your case, it would look like this:

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

(An astute reader will note right away that this ought to be :nth-child(odd of tr.row) instead, since the simple selectors tr and :nth-child() operate independently of one another as well. This is one of the problems with functional pseudo-classes that accept selectors, a can of worms I'd rather not open in the middle of this answer. Instead I'm going to go with the assumption that most sites will not have any other elements than tr elements as siblings of one another in a table body, which would make either option functionally equivalent.)

Of course, being a brand new proposal in a brand new specification, this probably won't see implementation until a few years down the road. In the meantime, you'll have to stick with using a script, as above.


1 If you specify a type or universal selector, it must come first. This does not change how selectors fundamentally work, however; it's nothing more than a syntactic quirk.

2 This was originally proposed as :nth-match(), however because it still counts an element relative only to its siblings, and not to every other element that matches the given selector, it has since as of 2014 been repurposed as an extension to the existing :nth-child() instead.

这篇关于我可以结合:nth-​​child()或:nth-​​of-type()与任意选择器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆