Что является более эффективным: .parent (). Parent (). Parent () ~ или ~ parent (". Foo") ~ или ~ closest (". Foo") - PullRequest
32 голосов
/ 15 февраля 2010

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

$(this).parent().parent().parent().parent().parent().animate(...);

$(this).parents(".foo").animate(...);

$(this).closest(".foo").animate(...);

Я подозреваю, что первое может быть, поскольку оно наиболее явное, но по причинам обслуживания (вложение может измениться) я предпочитаю второе. Все они кажутся для бесперебойной работы на практике.

Ответы [ 7 ]

53 голосов
/ 15 февраля 2010

Вот анализ:

  • parent() поднимается только на один уровень вверх в дереве DOM.
  • parents(".foo") подходит к корню и выбирает только те элементы, которые соответствуют данному селектору .foo.
  • closest(".foo") подходит к корню, но останавливается, когда элемент соответствует селектору .foo.

Так что я бы выбрал последний, closest(".foo"). Причина:

  • Это лучше, чем создание цепочки parent, потому что если ваш документ изменяется из-за того, что вы удалили или добавили одну иерархию, вам не нужно изменять код jQuery.
  • Это лучше, чем parents(".foo"), потому что оно останавливается, как только совпадение найдено.
8 голосов
/ 07 декабря 2012

Ну, ближайший полезен, только если вы идете вверх или на том же уровне на элементе «нажал».

Если, например, вам нужен следующий сценарий:

<div class="controls radio-other">
    <label class="radio"><input type="radio" name="item">Option one</label>
    <label class="radio"><input type="radio" name="item">Option two</label>
    <label class="radio"><input type="radio" name="item" class="other-option" data-othertarget="#otherone"> Other... </label>
    <input type="text" placeholder="Alternative answer" id="otherone" class="hidden">
</div>

Тогда closest('#otherone') не найдет скрытое текстовое поле на $('.other-option').click() Лучшее решение в этом сценарии - использовать $(this).parentsUntil('.radio-other').find('#otherone')

Глядя на мой ответ, я сделал jsperf , который отражает приведенный выше сценарий с различными решениями. Просто используйте то, что наиболее полезно для вашего HTML-сценария. В результате parent().parent() является самым быстрым методом, однако это не всегда хороший вариант, если ваш html более гибок в использовании. Добавьте родителя div и разрывы parent().parent().

6 голосов
/ 15 февраля 2010

Очень хорошо, что вы провели измерения производительности. Это именно то, что должно быть сделано в таких сценариях. Если на практике все работает гладко и вы удовлетворены производительностью, выберите наиболее читаемый (второй и третий выглядят нормально).

3 голосов
/ 15 февраля 2010

Мне кажется, я видел презентацию Джона Резига, в которой говорилось, что closest () более оптимизирован, и это имеет некоторый смысл. Closest () является более новым дополнением к jQuery и решает именно эту уродливую цепочку parent (). Parent (). С другой стороны, parent () возвращает массив родителей, который соответствует вашему классу foo, и является более жадным с точки зрения поиска по сравнению с closest (), который находит первый элемент и прекращает поиск.

Бьюсь об заклад, что closest () наиболее эффективен, если вы ищете ближайший матч.

2 голосов
/ 29 апреля 2010

Быстрый тест в Firefox 3.6.3 показывает, что parents('.foo').eq(0) на самом деле значительно быстрее, чем closest('.foo'). Это спорный вопрос, является ли это, как ремонтопригодны, но это может оказаться более «эффективным» в конкретных сценариях.

2 голосов
/ 15 февраля 2010

Вы также можете использовать parents('.foo:first'). Я думаю, это почти то же самое, что и closest().

2 голосов
/ 15 февраля 2010

Я не могу комментировать реальную скорость, однако первая связывает вас с определенной иерархией элементов, от которой я бы уклонился.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...