Что более эффективно:.parent(). Parent(). Parent() ~ или ~ parents ( ". Foo" ) ~ или ~ ближайший ( ". Foo" )
У меня есть тег A, который запускает анимацию этого великого праведного прадеда. Все следующее будет работать, но наиболее эффективно и почему?
$(this).parent().parent().parent().parent().parent().animate(...);
$(this).parents(".foo").animate(...);
$(this).closest(".foo").animate(...);
Я подозреваю, что первый может быть, поскольку он наиболее явный, но по причинам обслуживания (вложенность может измениться), я предпочитаю второй. Кажется, что все они работают плавно на практике.
Ответы
Ответ 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')
. Он спорный, является ли он пригодным для обслуживания, но может оказаться более "эффективным" в конкретных сценариях.
Ответ 8
Я нахожу этот сайт, объясняя вопрос, который вы хотите.
Использовать jQuery $.closest() vs $.parents()