:nth-of-type() 在 jQuery / Sizzle 中?
Posted
技术标签:
【中文标题】:nth-of-type() 在 jQuery / Sizzle 中?【英文标题】::nth-of-type() in jQuery / Sizzle? 【发布时间】:2011-01-06 19:01:58 【问题描述】:令我惊讶的是Sizzle(jQuery 使用的选择器引擎)带有内置的:nth-child()
选择器,但缺少:nth-of-type()
选择器。
为了说明:nth-child()
和:nth-of-type()
之间的区别并说明问题,请考虑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>
由于 Sizzle 使用浏览器原生的 querySelector()
和 querySelectorAll()
方法,如果它们存在(即在已经实现 Selectors API 的浏览器中),像 $('body p:nth-child');
这样的东西当然可以工作。但它在旧版浏览器中无法使用,因为 Sizzle 没有此选择器的备用方法。
是否可以轻松地将 :nth-of-type()
选择器添加到 Sizzle,或者在 jQuery 中实现它(也许通过使用 the built-in :nth-child()
selector)? custom selector with parameters 会很好。
【问题讨论】:
不确定,但$('p:even')
不会为您提供所需的内容吗?你已经有了选择器 (p
),所以你只需要过滤它。
@Kobi:没那么容易。选择器p:nth-child(2n)
将匹配每个父元素中 中的每隔一个段落。如果有两个 DIV,都包含三个段落,则以下段落(按 DOM 顺序)将与 p:nth-child(2n)
匹配:#2、#5。看?这不仅仅是获取文档中的每个P
,然后将其过滤到每个 mnth 元素的问题。是的,$('p:even')
是 $('p:nth-child(2n)')
的别名,但不是 $('p:nth-of-type(2n)')
的别名。另外,我在这个例子中使用了2n
,当然其他变体也应该是可能的。
知道了,并删除了我的答案。
Nick Craver,就像我在我的帖子中解释的那样,这是因为 Firefox 是具有选择器 API 的本机实现的浏览器之一。 Sizzle 不知道 :nth-of-type()
选择器,但 Firefox 的 querySelectorAll()
知道。这就是它“有效”的原因——但这并不是因为 Sizzle。最好在 Sizzle 中使用它,因为它可以在 所有 浏览器中使用。
你不知道吗,它没有实现仅仅是因为John Resig didn't think it was worth implementing。
【参考方案1】:
/**
* 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 -(签入 IE 或重命名选择器)
你当然也可以添加偶数&奇数:
match[3] = match[3] == "even" ? "2n" : match[3] == "odd" ? "2n+1" : match[3];
【讨论】:
酷!这就是我一直在寻找的;一个简短、聪明、简洁的解决方案。如您所知,:odd
和 :even
已经在 jQuery 中得到支持,只是不在 :nth-of-type(odd)
/ :nth-of-type(even)
形式中,但为了完整性,也可以将它们放在其中。
更新:更多选择器,见github.com/keithclark/JQuery-Extended-Selectors
很好,但我只是想警告其他人这个解决方案总是假设一个周期性(n)。我的意思是,像 :nth-of-type(2n)
和 :nth-of-type(2)
这样的过滤器将是相同的(当后者应该只是第二个元素,而不是所有偶数元素时)。【参考方案2】:
jQuery 插件 moreSelectors 支持 nth-of-type(以及许多其他选择器)。我建议要么使用它,要么简单地实现一个简单的插件,只实现你需要的确切选择器。您应该能够从那里复制粘贴代码。
黑客愉快!
【讨论】:
【参考方案3】:我不能假装知道 nth-of-type 是如何实现的,但是 jQuery 确实提供了一种机制,您可以通过它创建自己的自定义选择器。
以下问题涉及自定义选择器,可能会为您提供有用的见解
What useful custom jQuery selectors have you written?
【讨论】:
是的,我知道这一点……我可能应该将其添加到我的帖子中。以上是关于:nth-of-type() 在 jQuery / Sizzle 中?的主要内容,如果未能解决你的问题,请参考以下文章
[ jquery 选择器 :nth-of-type() ] 选取指定类型(p)父元素下的第几个子元素