寻找下一个匹配兄弟姐妹的高效,简洁方法? [英] Efficient, concise way to find next matching sibling?

查看:100
本文介绍了寻找下一个匹配兄弟姐妹的高效,简洁方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了使用nextAll:first伪类之外,还有一种更简洁但效率不低的方法来找到与给定选择器匹配的元素的下一个同级结构,但不是更简单但有效的方法吗?

Sticking to the official jQuery API, is there a more concise, but not less efficient, way of finding the next sibling of an element that matches a given selector other than using nextAll with the :first pseudo-class?

当我说官方API时,我的意思是不入侵内部结构,直接进入Sizzle,在组合中添加插件等.(如果我最终不得不这样做,那就可以了,但是那不是这个意思问题是.)

When I say official API, I mean not hacking internals, going straight to Sizzle, adding a plug-in into the mix, etc. (If I end up having to do that, so be it, but that's not what this question is.)

例如,鉴于此结构:

<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>

如果我在this中有一个div(也许在click处理程序中,无论如何)并且想要找到与选择器"div.foo"相匹配的下一个同级div,我可以这样做:

If I have a div in this (perhaps in a click handler, whatever) and want to find the next sibling div that matches the selector "div.foo", I can do this:

var nextFoo = $(this).nextAll("div.foo:first");

...并且可以正常工作(例如,如果我以五个"开头,它会跳过六个"和七个"并为我找到八个"),但是它很笨拙,如果我想匹配第一个在任何选择器中,它都会变得笨拙. (当然,这比原始DOM循环要简洁得多).

...and it works (if I start with "Five", for instance, it skips "Six" and "Seven" and finds "Eight" for me), but it's clunky and if I want to match the first of any of several selectors, it gets a lot clunkier. (Granted, it's a lot more concise than the raw DOM loop would be...)

我基本上想要:

var nextFoo = $(this).nextMatching("div.foo");

...其中nextMatching可以接受所有选择器.我总是很惊讶next(selector)没有执行此操作,但是却没有执行,并且文档清楚其功能,所以...

...where nextMatching can accept the full range of selectors. I'm always surprised that next(selector) doesn't do this, but it doesn't, and the docs are clear about what it does, so...

我总是可以编写并添加它,尽管如果这样做并坚持使用已发布的API,事情会变得非常低效.例如,一个naveve next循环:

I can always write it and add it, although if I do that and stick to the published API, things get pretty inefficient. For instance, a naïve next loop:

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已经过全面优化.上面的nave循环会创建并丢弃各种临时对象,并且每次都必须重新解析选择器,这并不奇怪,它很慢.

...is markedly slower than nextAll("selector:first"). And that's not surprising, nextAll can hand the whole thing off to Sizzle, and Sizzle has been thoroughly optimized. The naïve loop above creates and throws away all sorts of temporary objects and has to re-parse the selector every time, no great surprise it's slow.

当然,我不能只在最后扔一个:first:

And of course, I can't just throw a :first on the end:

jQuery.fn.nextMatching = function(selector) {
    return this.nextAll(selector + ":first"); // <== WRONG
};

...因为虽然它可以与简单的选择器(例如"div.foo")一起使用,但由于我提到的多个选择"选项(如"div.foo,div.bar")而失败.

...because while that will work with simple selectors like "div.foo", it will fail with the "any of several" option I talked about, like say "div.foo, div.bar".

编辑:抱歉,应该说:最后,我可以只使用.nextAll()然后在结果上使用.first(),但是jQuery将不得不访问所有同级对象,以便找到第一个.我希望它在获得比赛结果时停止,而不是浏览完整列表,只是这样它可以丢弃除第一个以外的所有结果. (尽管它似乎真的很快发生了;但请参见速度比较之前已链接.)

Edit: Sorry, should have said: Finally, I could just use .nextAll() and then use .first() on the result, but then jQuery will have to visit all of the siblings just to find the first one. I'd like it to stop when it gets a match rather than going through the full list just so it can throw away all results but the first. (Although it seems to happen really fast; see the last test case in the speed comparison linked earlier.)

谢谢.

推荐答案

您可以将多个选择器传递给 .nextAll() 并使用 .first() 这样的结果:

You can pass a multiple selector to .nextAll() and use .first() on the result, like this:

var nextFoo = $(this).nextAll("div.foo, div.something, div.else").first();

出于比较目的,此处将其添加到测试套件中:

Just for comparison, here it is added to the test suite: http://jsperf.com/jquery-next-loop-vs-nextall-first/2 This approach is so much faster because it's a simple combination of handing the .nextAll() selector off to native code when possible (every current browser) and just taking the first of the result set....way faster than any looping you can do purely in JavaScript.

这篇关于寻找下一个匹配兄弟姐妹的高效,简洁方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆