jQuery: nextEl = someEl.next(function() {... return true/false; })?
How can I get the nearest next element that sattisfies some condition/function? Like:
nextEl = someEl.next(function() {... return true to return this from next() });
I'm not aware that the .next() method in jQuery API supports a function as an argument. Is there some trick to write it like this without doi开发者_开发问答ng a while loop?
Also I don't want to select all elements first and then use filter() -- this suboptimal from performance point of view.
Get all the next elements using .nextAll()
, then use .filter()
and return the result of the condition. When the condition returns true
, the element is kept.
Then narrow it down to the .first()
match.
nextEl = someEl.nextAll().filter(function() {
return ( someCondition );
}).first();
Or if there will be many elements tested, and you don't want to run the condition all those extra times, use .each()
, then return false;
when the condition is met. This halts the loop.
var nextEl;
someEl.nextAll().each(function() {
if( someCondition ) {
nextEl = this; // reference the matched element
return false; // break the loop
}
});
EDIT: If you don't want to select all the next elements, I'd go native, and use a while
loop, something like this:
var nextEl = someEl[0];
while( nextEl = nextEl.nextSibling ) {
if( someCondition ) {
break;
}
}
The loop will break as soon as the condition is met, and the most recent assignment to nextEl
will be your element.
If the condition is never met, the loop will end when it runs out of elements, and nextEl
will be null
or undefined
( I don't remember which ).
This should be a very quick way to do it.
EDIT:
Here's a function version of it. It accepts the starting element and a function that runs the test. Then it returns the match found, or undefined
.
function nextMatch( el, func ) {
while( el = el.nextSibling ) {
if( func() ) {
return el;
}
}
}
// nextEl will contain the match, or "undefined"
var nextEl = nextMatch( someEl, function() {
return (someTest);
});
var someOtherEl = nextMatch( someEl, function() {
return (someOtherTest);
});
LAST EDIT:
I guess I might as well make it into a plugin:
(function( $ ) {
$.fn.nextMatch = function( func ) {
return this.map(function() {
var el = this;
while( el = el.nextSibling ) {
if( el.nodeType === 1 && func.call( el ) ) {
return el;
}
}
});
}
})( jQuery );
var nextEl = someEl.nextMatch( function() {
return (someTest);
});
So now it's more of a jQuery type solution. You still should have better performance since it doesn't fetch all the next siblings, and the while
loop still breaks once a match is found.
Try this:
nextEl = someEl.nextAll('.a').first().css('color', 'red');
The condition is in this case that it has the class a
, and it turns the color red (merely as an indicator).
Look at it working here.
精彩评论