css nth-child(2n+1) repaint css after filtering out list items

自作多情 提交于 2019-12-01 09:03:30

Nth-child can be counterintuitive when working with a filtered selection of a group.

Use .each() to get around its limitations:

var count = 1;
$('#element tr:not(.isotope-hidden)').each(function(){
    if ( count++ % 2 == 1 ) $(this).css('background-color','white')
})
BoltClock

CSS selectors — in particular, pseudo-classes, and in particular :not() and the :nth-*() family of pseudo-classes — do not work as "filters"; there's a bit of an explanation here, although it seems a little awkward in retrospect. Here's a better explanation.

Simple selectors in a sequence aren't processed in the order they are written one by one; rather, they are a set of conditions that an element must match in order for styles to apply to it, and the element must match all these conditions as they are, together. Or instead of calling them conditions you could also call them descriptors, but I would consider "filters" a misnomer when it comes to CSS selectors.

Your selector means:

Select this element if and only if it is located within #element and it matches all these conditions:

  • It is a tr element
  • It does not have the class isotope-hidden
  • It is the (2n+1)th child of its parent

It does not mean:

  1. Look inside the contents of #element
  2. Select all tr elements
  3. Filter out elements that do not have the class isotope-hidden among these elements
  4. Apply styles to every (2n+1)th child among these filtered elements

Even if you could "repaint" or reapply styles after filtering them out, it wouldn't work anyway. This is because whether or not an element the isotope-hidden class (or even whether or not it's a tr!), the :not(.isotope-hidden) selector isn't going to change the fact that an element that is :nth-child(1) is the first child of its parent in the DOM, an element that is :nth-child(2) is the second child of its parent in the DOM, and so on.

If you need sequential filters, you won't be able to do this with a pure CSS selector; you'll have to use jQuery's filter methods, which were designed for this very purpose, to add a class to the respective elements which you can then use to apply your styles:

$('#element tr').not('.isotope-hidden').filter(':even');

As an aside, this can also be rewritten as a single jQuery selector, using its filter selectors:

$('#element tr:not(.isotope-hidden):even');

However, despite the similar syntax, there is a vast difference between true CSS selectors and jQuery filters, which is outlined in this answer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!