jQuery: nextEl = someEl.next (function () {... return true / false;})? - PullRequest
0 голосов
/ 26 ноября 2010

Как я могу получить ближайший следующий элемент, который удовлетворяет некоторому условию / функции? Как:

nextEl = someEl.next(function() {... return true to return this from next() });

Мне не известно, что метод .next () в jQuery API поддерживает функцию в качестве аргумента. Есть ли какая-то хитрость, чтобы написать это так, не делая цикл while?

Также я не хочу сначала выбирать все элементы, а затем использовать filter () - это неоптимально с точки зрения производительности.

Ответы [ 2 ]

2 голосов
/ 26 ноября 2010

Получите все следующие элементы , используя .nextAll(), затем используйте .filter() и верните результат условия.Когда условие возвращает true, элемент сохраняется.

Затем сузьте его до совпадения .first().

nextEl = someEl.nextAll().filter(function() {
    return ( someCondition );
}).first();

Или, если будет проверено много элементов, и вы не хотите запускатьподготовьте все эти дополнительные времена, используйте .each(), затем return false;, когда условие выполнено.Это останавливает цикл.

var nextEl;

someEl.nextAll().each(function() {
    if( someCondition ) {
        nextEl = this;  // reference the matched element
        return false;   // break the loop
    }
});

РЕДАКТИРОВАТЬ: Если вы не хотите выбирать все следующие элементы, я бы стал нативным,и используйте цикл while, что-то вроде этого:

var nextEl = someEl[0];

while( nextEl = nextEl.nextSibling ) {
    if( someCondition ) {
        break;
    }
}

Цикл прервется, как только будет выполнено условие, и вашим элементом будет последнее присвоение nextEl.

Если условие никогда не выполняется, цикл заканчивается, когда в нем заканчиваются элементы, и nextEl будет null или undefined (я не помню, какое).

Это должен быть очень быстрый способ сделать это.


РЕДАКТИРОВАТЬ:

Вот его функциональная версия.Он принимает начальный элемент и функцию, которая запускает тест.Затем он возвращает найденное совпадение или 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);
});

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ:

Полагаю, я мог бы также превратить его в плагин:

(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);
});

Так что теперь это скорее решение типа jQuery.Вы по-прежнему должны иметь лучшую производительность, так как он не выбирает всех следующих братьев и сестер, а цикл while все еще прерывается, как только найдено совпадение.

1 голос
/ 26 ноября 2010

Попробуйте это:

nextEl = someEl.nextAll('.a').first().css('color', 'red');

Условие в этом случае, что у него есть класс a, и он становится красным (просто как индикатор).

Посмотрите, как это работает здесь .

...