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

前端 未结 2 1945
广开言路
广开言路 2021-01-14 00:28

I have a list of 20+ items. The background-color changes using the :nth-child(2n+1) selector. (ie. even item black, odd item white). When I click a button to filter out spec

相关标签:
2条回答
  • 2021-01-14 01:26

    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')
    })
    
    0 讨论(0)
  • 2021-01-14 01:29

    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.

    0 讨论(0)
提交回复
热议问题