Какая разница между .closest() и .parents('selector')?

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

<table>
    <tr>
        <td>...</td>
        <td><span class='toggle'>Toggle</span></td>
    </tr>
    <tr>
        <td>...</td>
        <td><span class='toggle'>Toggle</span></td>
    </tr>
    <tr>
        <td>..</td>
        <td><span class='toggle'>Toggle</span></td>
    </tr>
</table>

Из тегов <span> я мог бы использовать $(this).closest('tr'); или $(this).parents('tr'); для доступа к тегу parent/closeest <tr>.

Ответ 1

parent возвращает непосредственных родителей (по одному для каждого элемента в объекте вызывающего) или ничего, если родительский элемент не соответствует селектору. closest возвращает ближайшего предка, соответствующего предшественнику для каждого элемента (который может быть исходным элементом). Третья аналогичная функция parents возвращает всех соответствующих предков (не включая сам элемент).

Как правило, closest более устойчив к рефакторингу кода HTML, чем parent, если вы выбрали селектор разумно.

Ответ 2

(Примечание: вопрос был изменен на следующий день после того, как его спросили, изменив вопрос примерно с parent на parents [обратите внимание на множественное число]. Какой вид имеет значение!)

Повторите свой оригинальный вопрос о parent (единственном числе) против closest: parent только когда-либо на один уровень вверх, closest начинается с текущего элемента (а не только из родителя) и продолжает поиск через предков, пока не найдет совпадение (или закончится предками).

Повторите свой обновленный вопрос parents (множественное число) и closest: существуют две отличия:

  • Рассматривается ли текущий элемент (это с closest, это не с parents).

  • Если поиск останавливается с первым совпадением (он работает с closest, он не с parents).

Из вашего оригинального вопроса:

Из тегов я мог бы использовать либо $(this).closest('tr'); или $(this).parent('tr');

Нет, на самом деле. $(this).parent('tr'); возвращает пустой объект jQuery, поскольку родительский элемент span не соответствует селектору.

Из вашего обновленного вопроса:

Из тегов я мог бы использовать либо $(this).closest('tr'); или $(this).parents('tr');

Вы можете, при условии, что ваш tr также не находится в пределах другого tr (например, таблицы, содержащей таблицу). Если это произойдет, вы получите тот же результат. Но если у вас есть таблица внутри таблицы, parents вы получите несколько tr ( всех элементов предка tr).

Рассмотрим эту структуру:

<div class="wrapper">
  <div class="inner">
    <p>Testing <span>1 2 3</span></p>
  </div>
</div>

Если мы привязаем click к span, это то, что мы возвращаем из трех соответствующих методов:

  • $(this).parent('div') - пустой объект jQuery, родительский элемент span не является div.
  • $(this).parents('div') - объект jQuery с двумя div в нем, "внутренним" и "обертовым" divs (в этом порядке).
  • $(this).closest('div') - объект jQuery с одним div в нем, "внутренний".

Здесь результат, если мы зацепим click на span и используем span в качестве селектора:

  • $(this).parent('span') - пустой объект jQuery, родительский элемент span не является span.
  • $(this).parents('span') - пустой объект jQuery, span не имеет предка span s.
  • $(this).closest('span') - объект jQuery с кликом span.

Ответ 3

.parent() только поднимается на один уровень, а closest() включает текущий элемент и всех родителей.

Пример (выбор из нижней части div, x= согласованных элементов):

             parent()  parent('body')   .closest('div')  .parents('div')
body     
   div                                                       x
      div       x        <nothing>                           x
this-->   div                                x