Jquery функция $.find()
Определение и применение
Функция $.find() находит DOM-элементы по селектору и возвращает их без обёртки jQuery. Она полезна, когда компонент уже работает с обычными элементами, но ему нужны селекторы jQuery. Например, плагин может найти товары внутри своего контейнера, отобрать часть заранее собранного массива или проверить одну карточку.
Для обычной цепочки действий удобнее .find(): метод вызывается у коллекции и возвращает коллекцию. Низкоуровневые функции ниже рассматриваются для полной jQuery 4.0.0.
Синтаксис и результат
const elements = $.find(selector, context, results);
const filtered = $.find.matches(selector, elements);
const matches = $.find.matchesSelector(element, selector);| Вызов | Что делает | Результат |
|---|---|---|
$.find(selector, context) | Ищет элементы внутри контекста | Массив DOM-элементов |
$.find.matches(selector, elements) | Фильтрует переданный массив элементов | Массив подходящих элементов |
$.find.matchesSelector(element, selector) | Проверяет один DOM-элемент | true или false |
selector — строка селектора. Для $.find() контекстом служит DOM-элемент, документ или DocumentFragment; если его не передать, поиск начинается в document. Передавайте container или $(container)[0], а не объект $(container). Для поиска по обычному селектору элемент-контекст сам в результат не включается.
Необязательный results — массив или совместимый объект с length и push. Функция дописывает найденные элементы в него и возвращает этот же объект. Уже находящиеся там элементы не очищаются. Повторные вызовы с одним массивом могут накопить дубликаты; для независимого поиска не передавайте старый массив.
У matches() порядок аргументов начинается с селектора, а у matchesSelector() — с элемента. Пустой массив для фильтрации даёт пустой результат. Не передавайте вместо элемента null: сначала проверьте, что поиск элемента завершился успешно.
Поиск, фильтрация и проверка карточки
В первом контейнере находятся два товара, во втором — ещё один. Пример ищет доступные товары только в первом контейнере, затем фильтрует массив из обоих контейнеров и отдельно проверяет первую карточку. Результаты показывают, что область поиска и исходный массив — разные ограничения.
Найти товары в контейнере и отфильтровать массив: попробуйте сами
index.html
<section id="first">
<h2>Первый каталог</h2>
<p class="product available">Книга</p>
<p class="product">Карандаш</p>
</section>
<section id="second">
<h2>Второй каталог</h2>
<p class="product available">Блокнот</p>
</section>
<pre id="result" aria-label="Результат поиска"></pre>
main.js
const first = document.getElementById('first');
const all = Array.from(document.querySelectorAll('.product'));
const names = elements => elements.map(element => element.textContent.trim()).join(', ');
const found = $.find('.product.available', first);
const filtered = $.find.matches('.available', all);
const isAvailable = $.find.matchesSelector(all[0], '.available');
const accumulated = [all[1]];
const returned = $.find('.product.available', first, accumulated);
document.getElementById('result').textContent = [
'В первом каталоге: ' + names(found),
'В общем массиве: ' + names(filtered),
'Книга доступна: ' + isAvailable,
'С добавлением к массиву: ' + names(accumulated),
'Возвращён тот же массив: ' + (returned === accumulated),
'Массив: ' + Array.isArray(found),
'Коллекция jQuery: ' + ($(first).find('.available').jquery === $.fn.jquery)
].join('\n');
Нажмите , чтобы запустить пример.
Ожидаемый результат: поиск внутри первого контейнера находит «Книгу», фильтрация общего массива — «Книгу» и «Блокнот». Проверка книги возвращает true. У коллекции $(first).find() есть методы jQuery, у массива из $.find() — обычные методы массива. Чтобы применить метод jQuery к найденным узлам, явно оберните результат: $(elements).addClass("selected").
Собственный псевдокласс через $.expr
Псевдокласс — условие выбора элемента после двоеточия в селекторе. В jQuery можно добавить своё условие через $.expr.pseudos. Без аргумента оно представляет собой функцию проверки элемента. Для условия с аргументом используйте $.expr.createPseudo(): фабрика получает текст аргумента и возвращает функцию проверки.
Во втором примере :catalogAvailable проверяет наличие товара, а :catalogMinPrice(100) — минимальную цену. Фабрика один раз преобразует аргумент в число; затем проверяющая функция сравнивает его с ценой каждой карточки.
Добавить условия наличия и минимальной цены: попробуйте сами
index.html
<section id="catalog">
<h2>Каталог</h2>
<p class="product" data-stock="yes" data-price="120">Книга</p>
<p class="product" data-stock="yes" data-price="20">Карандаш</p>
<p class="product" data-stock="no" data-price="200">Альбом</p>
</section>
<pre id="result" aria-label="Результат фильтрации"></pre>
main.js
$.expr.pseudos.catalogAvailable = element => element.dataset.stock === 'yes';
$.expr.pseudos.catalogMinPrice = $.expr.createPseudo(argument => {
const minimum = Number(argument);
return element => {
const price = element.dataset.price;
return price !== undefined && price !== '' && Number.isFinite(minimum) &&
Number.isFinite(Number(price)) && Number(price) >= minimum;
};
});
const selected = $.find('.product:catalogAvailable:catalogMinPrice(100)', document.getElementById('catalog'));
document.getElementById('result').textContent = 'Доступны от 100: ' +
selected.map(element => element.textContent.trim()).join(', ');
Нажмите , чтобы запустить пример.
Среди доступных товаров ценой от 100 остаётся только «Книга». Эти псевдоклассы существуют в движке jQuery: передавать их напрямую в querySelectorAll() нельзя. Регистрация глобальна для экземпляра jQuery, поэтому выбирайте имя с префиксом своего компонента и не переопределяйте встроенные имена. Условие проверки не должно менять DOM.
Если правило используется в одном месте, обычно проще $(elements).filter(elementPredicate). Помните, что у функции, переданной в .filter(), первый аргумент — индекс, а элемент — второй; её сигнатура отличается от функции в $.expr.pseudos.
Ограничения и типичные ошибки
- Обычный поиск по стандартному CSS-селектору часто можно решить через
querySelectorAll(), а проверку элемента — черезelement.matches(). Подключать jQuery только ради этого не требуется. - Селектор и набор элементов — разные данные. Не собирайте селектор из произвольного пользовательского текста. Для динамического идентификатора экранируйте именно его значение через
$.escapeSelector(); ошибочный синтаксис селектора может вызвать исключение. - Результаты не являются живым списком: после добавления карточки в DOM нужно повторить поиск. Фильтрация готового массива не добавляет в него новых потомков.
- Позиционные условия вроде
:firstотносятся к набору элементов. Для проверки отдельной карточки выбирайте условие, описывающее сам элемент, например класс или атрибут.
Что проверено для jQuery 4.0
В исходниках 4.0.0 сохранены $.expr.pseudos и $.expr.createPseudo(). Старые инструкции с $.expr.order, $.expr.match.POS и прежней сигнатурой setFilters нельзя механически переносить из документации Sizzle. Внутренние $.find.compile, select, setDocument и tokenize оставлены для обратной совместимости; сама реализация помечает их приватными. Для прикладного кода используйте описанные выше операции, а не внутренний компилятор.