У меня есть тег, который инициировал анимацию, он - great-great-great-grandparent. Все следующее будет работать, но который является самым эффективным, и почему?
$(this).parent().parent().parent().parent().parent().animate(...);
$(this).parents(".foo").animate(...);
$(this).closest(".foo").animate(...);
Я подозреваю, что первое могло бы быть, поскольку это является самым явным, но по причинам обслуживания (вложение может измениться), я предпочитаю второе. Они все, кажется, работают гладко на практике.
Очень хорошо, что вы провели измерения производительности. Именно это и нужно делать в таких сценариях. Если на практике все работает гладко, и вы удовлетворены производительностью, выберите наиболее читаемый (второй и третий выглядят нормально).
Вы также можете использовать parents('.foo:first')
. Я полагаю, это практически то же самое, что и closest()
.
Вот анализ:
parent()
идет на один уровень вверх по дереву DOM. parents(".foo")
идет до корня и выбирает только те элементы, которые соответствуют заданному селектору .foo
. closest(".foo")
идет до корня, но останавливается, как только элемент соответствует селектору .foo
. Поэтому я бы выбрал последний вариант, closest(".foo")
. Причина:
parent
, потому что если ваш документ изменится, потому что вы удалили или добавили одну иерархию, вам не нужно менять код jQuery. parents(".foo")
, потому что он останавливается, как только найдено совпадение. Я не могу комментировать реальную скорость, однако первый вариант привязывает вас к определенной иерархии элементов, от которой я бы уклонился.
Лично я стараюсь редко использовать селекторы классов. Я понимаю, что часто нет другого пути, но если я могу добавить селектор ID, то я знаю, что производительность в любом случае улучшится.
Мне кажется, я видел презентацию Джона Ресига, в которой говорилось, что closest () более оптимизирован и делает какой-то смысл. Closest () - это новое дополнение к jQuery, которое решает именно эту уродливую цепочку parent (). Parent (). С другой стороны, parent () возвращает массив родителей, соответствующих вашему классу foo, и является более жадным с точки зрения поиска по сравнению с closest (), которая находит первый элемент и прекращает поиск.
Могу поспорить, что closest () является наиболее эффективным, если вы ищете наиболее близкое соответствие.
Быстрый тест в Firefox 3.6.3 показал, что parents('.foo').eq(0)
действительно значительно быстрее, чем closest('.foo')
. Спорно, насколько он удобен в обслуживании, но в конкретных сценариях он может оказаться более "эффективным".