Как выбрать последовательные элементы, которые соответствуют фильтру - PullRequest
7 голосов
/ 17 сентября 2008

Данный пример:

<img class="a" />
<img />
<img class="a" />
<img class="a" id="active" />
<img class="a" />
<img class="a" />
<img />
<img class="a" />

(я только что использовал теги img в качестве примера, это не то, что есть в моем коде)

Используя jQuery, как бы вы выбрали теги img с классом "a", которые примыкают к #active (в этом примере - средней четверке)?

Вы могли бы сделать это довольно легко, зацикливаясь на всех следующих и предыдущих элементах, останавливаясь при сбое условия фильтра, но мне было интересно, может ли jQuery это сделать изначально?

Ответы [ 6 ]

4 голосов
/ 17 сентября 2008

Вот что я в итоге придумал.

// here's our active element.
var $active = $('#active');

// here is the filter we'll be testing against.
var filter = "img.a";

// $all will be the final jQuery object with all the consecutively matched elements.
// start it out by populating it with the current object.
var $all = $active;

for ($curr = $active.prev(filter); $curr.length > 0; $curr = $curr.prev(filter)) {
    $all = $all.add($curr);
}
for ($curr = $td.next(filter); $curr.length > 0; $curr = $curr.next(filter)) {
    $all = $all.add($curr);
}

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


Редактировать : С тех пор я обнаружил, что функция each () могла бы сделать это довольно хорошо для некоторых целей. В моем собственном случае это работает не так чисто, так как я хочу один объект jQuery для всех этих элементов, но вот как вы можете использовать каждый из них для разных целей (в этом примере скрывая последовательные элементы «.a»:)

$('#active')
    .nextAll()
    .each(hideConsecutive)
    .end()
    .prevAll()
    .each(hideConsecutive)
;
function hideConsecutive(index, element) {
    var $e = $(element);
    if (!$e.is(".a")) {
        return false;    // this stops the each function.
    } else {
        $e.hide('slow');
    }
}

-

Редактировать: Теперь я собрал это в плагин. Посмотрите на http://plugins.jquery.com/project/Adjacent, если вам интересно.

2 голосов
/ 17 сентября 2008

Я считаю, что цикличность - ваш лучший выбор. Но вы можете попробовать, каждый активный, а затем двигаться до и после, пока условие не нарушится, что, если набор достаточно большой, будет быстрее.

1 голос
/ 18 апреля 2009

В приведенном ниже коде будут добавлены две новые функции: nextConsecutive () и prevConsecutive (). Они должны делать то, что вы хотите.

$. Каждый (['prev', 'next'], функция (unusedIndex, name) { $ .fn [имя + «Последовательный»] = функция (matchExpr) {

    var $all = 
        (name == 'prev')
             ? $(this).prevAll()
             : $(this).nextAll();
    if (!matchExpr)
        return $all;

    var $notMatch = $($all).not(matchExpr).filter(':first');
    if ($all.index($notMatch) != -1)
        return $allConsecutive = $all.slice(0, $all.index($notMatch));

    return $all;
};

});

0 голосов
/ 17 сентября 2008

Это еще один способ сделать это, хотя ответ селектора брата довольно классный:

var next = $('#active').next('.a');
var prev = $('#active').prev('.a');

Редактировать: Я перечитал ваши требования, и это не совсем то, что вы хотите. Вы можете использовать nextAll и prevAll, но они также не остановятся на IMG без имени класса.

0 голосов
/ 17 сентября 2008

@ Prestaul

$('#active ~ img.a')

выберет только следующих братьев и сестер и будет также включать непоследовательных братьев и сестер. Документы: http://docs.jquery.com/Selectors/siblings#prevsiblings

0 голосов
/ 17 сентября 2008

Тильда (~) - это селектор братьев и сестер :

$('#active ~ img.a').hide();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...