jQuery находит ближайшего предыдущего брата с классом

Вот грубый HTML, с которым я работаю:

<li class="par_cat"></li>
<li class="sub_cat"></li>
<li class="sub_cat"></li>
<li class="par_cat"></li> // this is the single element I need to select
<li class="sub_cat"></li>
<li class="sub_cat"></li>
<li class="sub_cat current_sub"></li> // this is where I need to start searching
<li class="par_cat"></li>
<li class="sub_cat"></li>
<li class="par_cat"></li>

Мне нужно пройти от .current_sub, найти ближайший предыдущий .par_cat и сделать с ним что-то.

.find("li.par_cat") возвращает всю загрузку .par_cat (у меня около 30 на странице). Мне нужно нацелиться на одного.


person daulex    schedule 22.02.2010    source источник


Ответы (5)


Пытаться:

$('li.current_sub').prevAll("li.par_cat:first");

Протестировал его с вашей разметкой:

$('li.current_sub').prevAll("li.par_cat:first").text("woohoo");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="par_cat"></li>
  <li class="sub_cat"></li>
  <li class="sub_cat"></li>
  <li class="par_cat">// this is the single element I need to select</li>
  <li class="sub_cat"></li>
  <li class="sub_cat"></li>
  <li class="sub_cat current_sub">// this is where I need to start searching</li>
  <li class="par_cat"></li>
  <li class="sub_cat"></li>
  <li class="par_cat"></li>
</ul>

заполнит ближайший предыдущий li.par_cat woohoo.

person karim79    schedule 22.02.2010
comment
спасибо Карим. Это тоже работало хорошо, но я предполагаю, что .prev() будет потреблять меньше ресурсов, так как .prevAll получит ВСЕ предыдущие совпадающие элементы, а затем отфильтрует тот, который мне нужен. Принятие ответа Эда. - person daulex; 22.02.2010
comment
На самом деле, после небольшого количества текстовых сообщений .prev() в нескольких случаях не работал. .prevAll с :first работало каждый раз. Спасибо. - person daulex; 22.02.2010
comment
.prev() проверяет только непосредственно предшествующий элемент. Я добавил комментарий к ответу ниже вместе с примером jsFiddle. Оглядевшись вокруг, это лучший ответ, поскольку, хотя он должен циклически перебирать все элементы, ему не требуются две функции, чтобы захватить все, а затем отфильтровать, чтобы найти его. - person David Hobs; 27.06.2012
comment
Означает ли это, что :first работает со списком возвращаемых элементов, который начинается ближе всего к выбранному объекту (а не сверху вниз относительно страницы)? - person NReilingh; 10.03.2013
comment
да, :first необходим, иначе будут выбраны все предыдущие. Большое спасибо за этот ответ - person Johansrk; 12.04.2014
comment
Большое спасибо за очень полезный ответ. Не могли бы вы ответить на вопрос @NReilingh, потому что это меня действительно смущает. Разве :first не является селектором CSS, который выбирает первый элемент в DOM (например, div.red:first выберет первый красный DIV в DOM). jQuery по-разному анализировал селектор? - person Accountant م; 26.07.2017
comment
@Accountantم Нет селектора CSS с именем :first. - person TylerH; 22.10.2020
comment
@TylerH о, теперь это имеет смысл, спасибо. Это селектор только для jQuery, и его можно свободно анализировать по своему усмотрению: D. - person Accountant م; 22.10.2020

Пытаться

$('li.current_sub').prev('.par_cat').[do stuff];
person Ed James    schedule 22.02.2010
comment
Чего ждать? Разве это не проверяет только непосредственно предшествующий элемент? Таким образом, ваш код вернет null? - Здесь проверено на jsFiddle: jsfiddle.net/Y2TEH - person David Hobs; 27.06.2012
comment
@DavidHobs Я написал это два года назад .... Я бы определенно использовал prevAll () в эти дни. - person Ed James; 27.06.2012
comment
@EdWoodcock рассмотрите возможность обновления своего ответа в этом случае. - person Hugo Zink; 10.11.2015

Использование prevUntil() позволит нам получить удаленного брата без необходимости получать все. У меня был особенно длинный набор, который слишком интенсивно использовал процессор, используя prevAll().

var category = $('li.current_sub').prev('li.par_cat');
if (category.length == 0){
  category = $('li.current_sub').prevUntil('li.par_cat').last().prev();
}
category.show();

Это получает первого предшествующего брата, если он совпадает, в противном случае он получает брата, предшествующего тому, который соответствует, поэтому мы просто создаем резервную копию еще одного с помощью prev(), чтобы получить желаемый элемент.

person eprothro    schedule 09.11.2012

Я думаю, что во всех ответах чего-то не хватает. Я предпочитаю использовать что-то вроде этого

$('li.current_sub').prevUntil("li.par_cat").prev();

Избавляет вас от необходимости добавлять :first внутри селектора, и его легче читать и понимать. Метод prevUntil() также имеет лучшую производительность, чем метод prevAll().

person Tom McDonough    schedule 08.11.2016
comment
Сначала я попробовал это, получилось так, что prevUntil возвращает много элементов, а затем получает prev() для каждого из многих элементов. Желаемый результат - один элемент - person JasonWilson; 17.08.2020

Вы можете следовать этому коду:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        $(".add").on("click", function () {
            var v = $(this).closest(".division").find("input[name='roll']").val();
            alert(v);
        });
    });
</script>
<?php

for ($i = 1; $i <= 5; $i++) {
    echo'<div class = "division">'
        . '<form method="POST" action="">'
        . '<p><input type="number" name="roll" placeholder="Enter Roll"></p>'
        . '<p><input type="button" class="add" name = "submit" value = "Click"></p>'
        . '</form></div>';
}
?>

Вы можете получить представление об этом.

person AL MaMun    schedule 19.09.2018