jquery - Efficient, concise way to find next matching sibling? -


sticking official jquery api, there more concise, not less efficient, way of finding next sibling of element matches given selector other using nextall :first pseudo-class?

when official api, mean not hacking internals, going straight sizzle, adding plug-in mix, etc. (if end having that, it, that's not question is.)

e.g, given structure:

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

if have div in this (perhaps in click handler, whatever) , want find next sibling div matches selector "div.foo", can this:

var nextfoo = $(this).nextall("div.foo:first"); 

...and works (if start "five", instance, skips "six" , "seven" , finds "eight" me), it's clunky , if want match first of of several selectors, gets lot clunkier. (granted, it's lot more concise raw dom loop be...)

i want:

var nextfoo = $(this).nextmatching("div.foo"); 

...where nextmatching can accept full range of selectors. i'm surprised next(selector) doesn't this, doesn't, , docs clear does, so...

i can write , add it, although if , stick published api, things pretty inefficient. instance, 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; }; 

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

and of course, can't throw :first on end:

jquery.fn.nextmatching = function(selector) {     return this.nextall(selector + ":first"); // <== wrong }; 

...because while work simple selectors "div.foo", fail "any of several" option talked about, "div.foo, div.bar".

edit: sorry, should have said: finally, use .nextall() , use .first() on result, jquery have visit of siblings find first one. i'd stop when gets match rather going through full list can throw away results first. (although seems happen really fast; see last test case in speed comparison linked earlier.)

thanks in advance.

you can pass multiple selector .nextall() , use .first() on result, this:

var nextfoo = $(this).nextall("div.foo, div.something, div.else").first(); 

edit: comparison, here added test suite: http://jsperf.com/jquery-next-loop-vs-nextall-first/2 approach faster because it's simple combination of handing .nextall() selector off native code when possible (every current browser) , taking first of result set....way faster looping can purely in javascript.


Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -