2

I have the following html structure:

<ul class="products">
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
</ul>

I having the following jquery:

$(".products li:nth-child(4)").addClass("last");

As you can see the above will add a class of last to every 4th <li>.

However in my HTML there might be a hidden <li> using display:none; via jquery.

Is there a way to skip past the hidden elements? So in theory i should have the following:

<ul class="products">
<li><a href="#"></a></li>
<li style="display:none;"><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li class="last"><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li class="last"><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
</ul>
danyo
  • 5,686
  • 20
  • 59
  • 119

4 Answers4

9

You can simply limit your selection to exclude hidden items:

$('.products li').filter(':visible');

Unfortunately you can't use nth selectors here, since you don't want to count the hidden elements., so you could just iterate over the items and change every fourth one.

$('.products li').filter(':visible').each(function(i) {
    var modulus = (i + 1) % 4;
    if (modulus === 0) { 
        $(this).addClass('last');
    }
});
Mike Brant
  • 70,514
  • 10
  • 99
  • 103
3

Maybe you could try using the index instead of using a selector of nth child, along with lorenzos solution?

$('li:visible').each(function(i){
    if((i+1) % 4 == 0){
        $(this).addClass('temp');
    }
});

UPDATED fiddle here

ntgCleaner
  • 5,865
  • 9
  • 48
  • 86
2

You can try this:

$('.products li:visible').filter(function(index){
    return !((index+1) % 4);
}).addClass('last')

Fiddle : http://jsfiddle.net/egQp7/

Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75
  • More or less same as the answer I had given. I would just comment that using `:visible` as part of the initial selector is an expensive operation, you should really, make a CSS-based selector and then use `filter()` on it to determine the visible elements. You could obviously just chain two `filter()` calls in a row to achieve this. – Mike Brant Jul 17 '13 at 23:39
  • Didnt know about that, but yeah, perfomance side, your answer is better! – Karl-André Gagnon Jul 17 '13 at 23:48
0

You can make your first selector select only visible elements, then use the jquery each() function's index to do some quick math and find every 4th element. A working example.

jquery:

$(".products li:visible").each(function(hiya){
    if((hiya+1) % 4 == 0){
        $(this).addClass('last');
    }
});

EDIT

Took out an unnecessary logical operator.

smilebomb
  • 5,123
  • 8
  • 49
  • 81