В моем опыте работы с javascript я обнаружил, что это очень распространенная задача «поиск ближайшего предка элемента с некоторым условием (имя тега, класс, ...)». Может ли jquery метод parent () выполнить эту работу? Порядок возвращаемых элементов parent () предсказуем? Сверху вниз или снизу вверх? На данный момент я использую эту служебную функцию:
function ancestor(elem, selector) {
var $elem = $( elem ).parent();
while( $elem.size() > 0 ) {
if ( $elem.is( selector ) )
return $elem;
else
$elem = $elem.parent();
}
return null;
}
Может ли кто-нибудь сказать мне, есть ли умный способ выполнить эту работу?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Редактировать: Начиная с jQuery 1.3, он был встроен как функция closest(). например: $('#foo').closest('.bar');
да - родители () пересекают дерево.
<div id = "a">
<div id = "b">
<p id = "c">
<a id = "d"></a>
</p>
</div>
</div>
$('#d').parents("div:first"); выберет div b.
К счастью, с тех пор команда jQuery закрыла этот билет с помощью wontfix. Так что .parents () снова следует считать стабильным.
Добавление к ответу @ Nickf:
jQuery 1.3 упростил эту задачу с помощью closest.
Учитывая DOM:
<div id = "a">
<div id = "b">
<p id = "c">
<a id = "d"></a>
</p>
</div>
</div>
Ты можешь сделать:
$('#d').closest("div"); // returns [ div#b ]
[Closest returns a] set of elements containing the closest parent element that matches the specified selector, the starting element included.
Проблема с .closest () в том, что он начинается с текущего элемента. Из сайт jQuery: «Получить первый элемент, соответствующий селектору, начиная с текущего элемента и продвигаясь вверх по дереву DOM». В общем, это не даст правильного ответа на вопрос, потому что ищет только элементы-предки.
Вам следует использовать closest, потому что parents не даст ожидаемого результата, если вы работаете с несколькими элементами. Например, допустим, у вас есть это:
<div id = "0">
<div id = "1">test with <b>nested</b> divs.</div>
<div id = "2">another div.</div>
<div id = "3">yet <b>another</b> div.</div>
</div>
и вы хотите добавить класс к div, у которых есть элемент <b> в качестве их непосредственного дочернего элемента (т. е. 1 и 3). Если вы используете $('b').parents('div'), вы получите divs 0, 1 и 3. Если вы используете $('b').parents('div:first'), вы получите только div 1. Чтобы получить 1 и 3, но не 0, вы должны использовать $('b').closest(elem).
Проблема с .closest () в том, что он начинается с текущего элемента. Из сайт jQuery: «Получить первый элемент, соответствующий селектору, начиная с текущего элемента и продвигаясь вверх по дереву DOM». В общем, это не даст правильного ответа на вопрос, потому что ищет только элементы-предки.
closest () начинается с текущего элемента, если родительский элемент, который вы ищете, имеет тот же тег, что и текущий (например, оба являются div), используйте parent (). closest ()
Остерегайтесь, Джон Ресиг планирует изменить .parents () так, чтобы элементы возвращались в исходном порядке. См. Эту ошибку, зарегистрированную самим Джоном после обсуждения на форуме порядка элементов внутри возвращаемых коллекций: bugs.jquery.com/ticket/5994