Combining jQuery: not and: nth-child selectors

$j('.select-all-these:not(.except-these):nth-child(3n)'); 

I am trying to select every third element that does not have a specific class. This is my jQuery selector, but it does not work - it seems that the nth-child selector is ignoring: not selector. Am I doing it wrong?

As an example, here's how it should work:

 .select-all-these.except-these .select-all-these.except-these .select-all-these.except-these .select-all-these .select-all-these.except-these .select-all-these .select-all-these <-- THIS ONE IS SELECTED .select-all-these.except-these 

Thanks!:)

+4
source share
5 answers

The only way I could see this work was to use two calls to filter() :

 $('.select').filter( function(){ return !$(this).hasClass('dontselect'); }).filter( function(i){ return (i+1)%3 == 0; // unless you want a zero-based count, regular CSS is one-based }).css('color','red'); 

JS Fiddle demo .

You could use a single filter() call with an external variable:

 var count = 0; $('.select').filter( function(){ console.log(!$(this).hasClass('dontselect')); if (!$(this).hasClass('dontselect')){ count++; return count%3 == 0; } }).css('color','red'); 

JS Fiddle demo .

JS Perf reports that a single filter is not surprising, a little faster , but only very, very, very little.

Literature:

+5
source

How to use the method to filter the results?

 $('.select-all-these:nth-child(3n)').not('.except-these'); 

Here is a script to demonstrate: http://jsfiddle.net/ntNgC/

+6
source

UPDATE: I don't think this is possible with nth-child or another jQuery selector. therefore, consider using a more detailed solution:

 var count = 0; $('.select-all-these').each(function() { if(!$(this).hasClass('except-these')) { count++; } if(count === 3) { $(this).text('every 3rd element'); count = 0 } });​ 

http://jsfiddle.net/TJdFS/2/ (alternative version: http://jsfiddle.net/TJdFS/ )

: nth-child counts all matching elements, ignoring any additional filters, such as: not.

see jquery doc:

The nth-child (n) pseudo-class is easily confused with: eq (n), although the two can lead to completely different matched elements. Using nth-child (n), all child elements are taken into account, regardless of whether they are, and the specified element is selected only if it matches the selector attached to the pseudo-class. With the help of: eq (n), only the selector attached to the pseudo-class, not limited to the children of any other element, is calculated, and the (n + 1) -th one (n is the 0-base) is selected.

Example:

 <div class="select-all-these">1</div> <div class="select-all-these except-these">2</div> <div class="select-all-these except-these">3</div> <div class="select-all-these">4</div> <div class="select-all-these except-these">5</div> <div class="select-all-these">6</div> 

JS:

 $('.select-all-these:not(.except-these):nth-child(6)').text('nth-child counts all elements (1 based!)'); $('.select-all-these:not(.except-these):eq(1)').text('eq counts only matching elements (0 based!)'); 

Result:

 1 2 3 eq counts only matching elements. (0 based!) 5 nth-child counts all elements (1 based!) 

http://jsfiddle.net/nFtkE/2/

+3
source

The easiest way =)

 $('table tr:not(.class)').eq(1); 

Good luck =)

+2
source

Nth-child may not be compatible with filtered group choices.

Use .each () to get around its limitations:

 var count = 0; $('.select-all-these:not(.except-these)').each(function(){ if ( count++ % 2 == 0 ) $(this).css('color','red') }) 
+1
source

All Articles