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.
$('p:even')
give you what you're looking for? You already have the selector (p
), so you just need to filter it. – Radiolocationp:nth-child(2n)
would match every second paragraph in every parent element. If there are two DIVs, both containing three paragraphs, the following paragraphs (in DOM order) would be matched byp:nth-child(2n)
: #2, #5. See? It’s not just a matter of getting everyP
in the document and then filtering it down to every mnth elementh. Yes,$('p:even')
is an alias for$('p:nth-child(2n)')
, but not for$('p:nth-of-type(2n)')
. Also, I’m using2n
in this example, but of course other variations should be possible as well. – Nieves$('body p:nth-of-type(n)').css('background', 'orange');
is working in firefox here on jQuery 1.4, are you asking how to implement this strictly for older browsers, e.g. implement only the fallback version? – Municipalize:nth-of-type()
selector, but Firefox’squerySelectorAll()
does. That’s why it ‘works’ — but it’s not thanks to Sizzle. It would be good to have this in Sizzle because then it would work in all browsers. – Nieves$('body p:nth-child')
works in every browser, because Sizzle has a built-in:nth-child()
selector. So, if the browser doesn’t implement the Selectors API, Sizzle just uses that instead. The problem is Sizzle lacks an:nth-of-type()
selector. – Nieves