坚持使用官方jQuery API,是否有更简洁但效率不低的方法来查找与给定选择器匹配的元素的下一个同级对象,而不是nextAll
与:first
伪类一起使用?
当我说官方API时,我的意思是不入侵内部结构,直接前往Sizzle,在组合中添加插件等。(如果我最终不得不这样做,那就是这样,但这不是这个问题。 )
例如,鉴于此结构:
<div>One</div>
<div class='foo'>Two</div>
<div>Three</div>
<div class='foo'>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div class='foo'>Eight</div>
如果我有一个div
in this
(也许在click
处理程序中,无论如何)并且想要找到与选择器“ div.foo”相匹配的下一个同级div,我可以这样做:
var nextFoo = $(this).nextAll("div.foo:first");
...并且可以正常工作(例如,如果我以“五个”开头,则跳过“六个”和“七个”并为我找到“八个”),但是它很笨拙,并且如果我要匹配任何一个中的第一个几个选择器,就会变得笨拙。(当然,这是一个很多更简洁比原始DOM循环将是...)
我基本上想要:
var nextFoo = $(this).nextMatching("div.foo");
...nextMatching
可以接受所有选择器 我总是很惊讶next(selector)
没有这样做,但是没有这么做,并且文档清楚其功能,所以...
我总是可以编写并添加它,尽管如果这样做并坚持使用已发布的API,事情将会变得非常低效。例如,一个朴素的next
循环:
jQuery.fn.nextMatching = function(selector) {
var match;
match = this.next();
while (match.length > 0 && !match.is(selector)) {
match = match.next();
}
return match;
};
...明显比慢nextAll("selector:first")
。这不足为奇,nextAll
可以将所有内容交给Sizzle,并且Sizzle已经过全面优化。上面的幼稚循环会创建并丢弃各种临时对象,并且每次都必须重新解析选择器,这并不奇怪,它很慢。
当然,我不能只:first
在结尾处抛出:
jQuery.fn.nextMatching = function(selector) {
return this.nextAll(selector + ":first"); // <== WRONG
};
...因为这将适用于“ div.foo”之类的简单选择器,但由于我提到的“多个选项”选项会失败,例如“ div.foo,div.bar”。
编辑:对不起,应该说:最后,我可以使用.nextAll()
然后.first()
对结果使用,但是jQuery将不得不访问所有同级对象以找到第一个。我希望它在获得比赛结果时停止,而不是浏览完整列表,这样它就可以丢弃除第一个以外的所有结果。(尽管它似乎发生得非常快;请参阅前面链接的速度比较中的最后一个测试用例。)
提前致谢。
.nextAll().first()
?