:nth-of-type() in jQuery / Sizzle?
css-selectors, jquery, jquery-selectors, selectors-api
Solution
/**
* Return true to include current element
* Return false to exclude current element
*/
$.expr[':']['nth-of-type'] = function(elem, i, match) {
if (match[3].indexOf("n") === -1) return i + 1 == match[3];
var parts = match[3].split("+");
return (i + 1 - (parts[1] || 0)) % parseInt(parts[0], 10) === 0;
};
Test case - (check in IE or rename the selector)
You can of course add even & odd too:
match[3] = match[3] == "even" ? "2n" : match[3] == "odd" ? "2n+1" : match[3];
Problem
It surprised me that Sizzle (the selector engine jQuery uses) comes with a built-in `:nth-child()` selector, but lacks an `:nth-of-type()` selector. To illustrate the difference between `:nth-child()` and `:nth-of-type()` and to illustrate the problem, consider the following HTML document: ``` <!doctype html> <html> <head> <meta charset="utf-8"> <title>:nth-of-type() in Sizzle/jQuery?</title> <style> body p:nth-of-type(2n) { background: red; } </style> </head> <body> <p>The following CSS is applied to this document:</p> <pre>body p:nth-of-type(2n) { background: red; }</pre> <p>This is paragraph #1.</p> <p>This is paragraph #2. (Should be matched.)</p> <p>This is paragraph #3.</p> <p>This is paragraph #4. (Should be matched.)</p> <div>This is not a paragraph, but a <code>div</code>.</div> <p>This is paragraph #5.</p> <p>This is paragraph #6. (Should be matched.)</p> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> <script> $(function() { // The following should give every second paragraph (those that had red backgrounds already after the CSS was applied) an orange background. // $('body p:nth-of-type(2n)').css('background', 'orange'); }); </script> </body> </html> ``` Since Sizzle uses the browser-native `querySelector()` and `querySelectorAll()` methods if those are present (i.e. in browsers that already implement the Selectors API), stuff like `$('body p:nth-child');` will of course work. It won’t work in older browsers though, because Sizzle has no fallback method for this selector. Is it possible to easily add the `:nth-of-type()` selector to Sizzle, or to implement it in jQuery (by using the built-in `:nth-child()` selector, perhaps)? A custom selector with parameters would be nice.