Как сообщить jQuery прекратить поиск DOM при обнаружении первого элемента?
Из того, что я понимаю, добавление .first()
или :first
к запросу не останавливает поиск DOM после первого совпадения. Он просто сообщает jQuery взять 1-й элемент из сопоставленной коллекции.
Если это так, то есть ли способ остановить поиск DOM после первого совпадения? Например, если я знаю, что результат этого запроса всегда будет единственным элементом, как можно сказать, что jQuery не тратит время на поиски?
Ответы
Ответ 1
Насколько я знаю, в данный момент в jQuery нет способа сделать это. Лучшее, что вы можете сделать, это $(selector).first()
, где selector
- стандартный селектор CSS, не содержащий селекторов, специфичных для Sizzle (поэтому не используйте :first
). В этом случае jQuery использует быстрый метод DOM querySelectorAll
в современных браузерах.
Вы можете получить оптимизацию вручную, используя метод DOM querySelector
, который построен для выбора только первого соответствия:
$.getFirst= function(selector) {
if ('querySelector' in document)
return $(document.querySelector(selector));
else
return $(selector).first();
}
однако сумма, которую вы сохраните, сделав это намного меньше, чем вы сохраните, убедившись, что querySelectorAll
можно использовать.
Ответ 2
:first
соответствует только одному элементу. его эквивалент :eq(0)
.
.first()
уменьшает набор согласованных элементов до первого в наборе.
поэтому использование :first
будет похоже на то, что вам нужно, но при ближайшем рассмотрении они сначала используют селектор, чтобы найти набор, а затем использовать первый.
Здесь есть некоторые комментарии и обсуждение здесь и здесь кажется, указывает, что :first()
не останавливается на первом элементе.
Литература:
http://api.jquery.com/first-selector/
http://api.jquery.com/first/
Ответ 3
Я не эксперт по внутренним jQuery, но я понимаю, что порядок, в котором jQuery может найти вещи, не обязательно является порядком их появления в DOM. Чтобы гарантировать, что вы получите элемент, который является первым в DOM, jQuery получает все и сортирует результат так, чтобы возвращался первый элемент.
Как вы заметили, это проблема производительности. Однако я не верю, что вы можете отключить это поведение.
Что вы можете сделать, так это сделать ваши запросы более конкретными, чтобы меньше было выбрано, а для jQuery меньше элементов для сортировки, чтобы найти первый. Например, $('li: first') не очень специфичен и будет медленным. $('# myList > li: first') теоретически будет намного быстрее (хотя я не тестировал его, чтобы проверить), потому что он будет искать только в одном списке, а также b) подсписки также будут исключены.
Если вы будете использовать все элементы в выборе для чего-то в какой-то момент, но нужно только первое в определенной точке, тогда имеет смысл запустить селектор, чтобы получить все ваши элементы и сохранить его в var, затем используйте .first(), чтобы получить первый элемент, когда вам это нужно.
var elems = $('li'), firstElem = elems.first ();
Теперь elems будет содержать полный набор, а firstElem будет содержать только первый элемент.
Конечно, вы также можете просто указать первый элемент в каждой группе, которую вы собираетесь выбрать для определенного класса, но это может считаться неэлегантным решением.