Подтвердить что ты не робот

Что более эффективно:.parent(). Parent(). Parent() ~ или ~ parents ( ". Foo" ) ~ или ~ ближайший ( ". Foo" )

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

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

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

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

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

4b9b3361

Ответ 1

Самый близкий может быть полезен только тогда, когда вы поднимаетесь или на том же уровне на элементе 'clicked'.

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

<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().

Ответ 2

Вот анализ:

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

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

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

Ответ 3

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

Ответ 4

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

Готов поспорить, что ближайший() наиболее эффективен, если вы ищете ближайшее совпадение.

Ответ 5

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

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

Ответ 6

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

Ответ 7

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