Селекторы jQuery: шпаргалка с примерами для jQuery 3.x и 4.0
Опубликовано: 26.09.2026 · Обновлено: 26.09.2026 · Актуально для jQuery 3.7.1 и 4.0.0
jQuery принимает обычные CSS-селекторы и добавляет к ним собственные псевдоклассы вроде :contains() или устаревших :eq()/:first. Там, где селектор — чистый CSS без таких расширений, jQuery 3.7+ и 4.0 отдают выборку напрямую браузерному querySelectorAll(); отдельного проекта Sizzle в современных версиях больше нет, его функции перенесены внутрь самой библиотеки и включаются в дело только для нестандартных частей селектора. Ниже — все селекторы jQuery по группам: что выбирают, рабочий пример и что из них уже устарело.
Базовые селекторы
Это тот же синтаксис, что в обычном CSS: тег, класс, id, звёздочка и группировка через запятую. Полный список категорий селекторов — на странице Selectors в справочнике.
| Селектор | Что выбирает | Пример |
* | Все элементы без исключения. Сам по себе почти не используется — обычно как часть более сложного селектора, например .list > * | $('*').length — селектор «Все» |
tag | Все элементы указанного тега | $('p') — селектор по тегу |
#id | Элемент с указанным id. В валидном HTML id уникален, поэтому селектор возвращает не больше одного элемента | $('#menu') — селектор по id |
.class | Все элементы с указанным классом в списке классов (у элемента их может быть несколько через пробел) | $('.card') — селектор по классу |
tag.class | Сужает поиск: элементы тега tag, у которых есть класс class | $('li.active') |
sel1, sel2 | Объединение результатов нескольких селекторов без дублей — «этот ИЛИ тот» | $('h1, h2, h3') |
Группировка через запятую — это не «выбрать первый, если он есть, иначе второй», а объединение: в набор попадёт всё, что подошло хотя бы под один из перечисленных селекторов, без повторов одного и того же элемента.
Иерархия: потомки и соседи
Четыре комбинатора описывают отношения между элементами в дереве DOM — кто чей родитель, ребёнок или сосед.
| Селектор | Что выбирает | Пример |
E F | Потомок — элемент F на любой глубине внутри E (ребёнок, внук, правнук и так далее) | $('.card p') — селектор «Потомок» |
E > F | Прямой ребёнок — только непосредственные дети E, без внуков | $('.list > li') — селектор «Дочерний» |
E + F | Соседний элемент сразу после E на том же уровне вложенности (только один, следующий сразу за ним) | $('h2 + p') — первый абзац сразу после каждого h2 |
E ~ F | Любой последующий сосед — все элементы F после E на одном уровне, а не только ближайший | $('h2 ~ p') — все абзацы после h2 до следующего заголовка того же уровня и далее |
Частая ошибка — спутать E F и E > F: если в разметке между блоком и нужным элементом появится ещё один уровень вложенности (например, обёртка div), селектор с > перестанет находить элемент, а обычный пробел — нет. Безопаснее для устойчивости к правкам вёрстки — потомок через пробел, а > — там, где важно исключить более глубокую вложенность (например, отличить пункты верхнего уровня меню от вложенного подменю).
Селекторы по атрибуту
Восемь вариантов сверки значения атрибута — от простого «атрибут присутствует» до сравнения по подстроке. Все они, кроме [A!=V], — часть стандартного CSS, поэтому jQuery отдаёт их напрямую в querySelectorAll().
| Селектор | Что выбирает | Пример |
[attr] | Есть атрибут attr, значение любое | $('[disabled]') — селектор «Есть атрибут» |
[attr=value] | Значение атрибута равно строке value целиком | $('[type="submit"]') — селектор «Равно» |
[attr!=value] | Расширение jQuery (не стандартный CSS): значение не равно value ИЛИ атрибута нет вовсе | $('input[type!="checkbox"]') — селектор «Не равно» |
[attr^=value] | Значение начинается со строки value | $('a[href^="https://"]') — селектор «Начинается с» |
[attr$=value] | Значение заканчивается строкой value | $('a[href$=".pdf"]') — селектор «Заканчивается на» |
[attr*=value] | Значение содержит подстроку value где угодно | $('[class*="col-"]') — селектор «Содержит» |
[attr~=value] | Значение — список слов через пробел, и value — одно из этих слов целиком | $('[class~="active"]') — селектор «Содержит слово» |
[attr|=value] | Значение равно value или начинается с value- (дефис как разделитель) — исторически для языковых кодов | $('[lang|="en"]') совпадёт с lang="en" и lang="en-US" — селектор «Префикс» |
Атрибутные селекторы можно комбинировать подряд — [type="text"][required] найдёт только текстовые поля с атрибутом required. Значение стоит заключать в кавычки всегда, а не только когда в нём пробелы или спецсимволы: так меньше риск сломать селектор при изменении значения в будущем, а форматирование остаётся единообразным по всему проекту. Двойные и одинарные кавычки внутри селектора равнозначны — выбирайте одни и придерживайтесь их, чтобы не путать со внешними кавычками JS-строки.
Отдельный частый случай — выбор по data-*: $('[data-user-id]') найдёт все элементы с этим атрибутом, а $('[data-user-id="42"]') — с конкретным значением. Важная тонкость: атрибутный селектор всегда читает то, что реально написано в HTML-разметке (или было туда явно записано через .attr()), а не то, что хранится во внутреннем кеше jQuery. Если значение положили через .data('userId', 42), а не через .attr('data-user-id', 42), атрибут в разметке не изменится — и селектор по нему ничего не найдёт, даже если .data('userId') в тот же момент честно вернёт 42.
Фильтры позиции (устарели)
Все семь позиционных фильтров из таблицы ниже официально помечены как deprecated начиная с jQuery 3.4 (сверено по списку deprecated на api.jquery.com): они по-прежнему работают в 3.x и в 4.0, но документация рекомендует заменить их методами, применёнными к уже найденному набору элементов, — так селектор до фильтрации остаётся чистым CSS и может целиком уйти в быстрый querySelectorAll().
| Селектор | Что выбирал | Замена |
:first | Первый элемент найденного набора | .first() — страница :first, метод .first() |
:last | Последний элемент набора | .last() |
:eq(n) | Элемент с индексом n (с нуля) | .eq(n) — страница :eq(), метод .eq() |
:gt(n) | Все элементы с индексом больше n | .slice(n + 1) — страница :gt(). Пример: :gt(3) → .slice(4) |
:lt(n) | Все элементы с индексом меньше n | .slice(0, n). Пример: :lt(3) → .slice(0, 3) |
:even | Элементы с чётным индексом (0, 2, 4…) | .even() (добавлен в jQuery 3.5.0) — страница :even |
:odd | Элементы с нечётным индексом (1, 3, 5…) | .odd() (добавлен в jQuery 3.5.0) |
На практике замена почти всегда однострочная:
// Старый вариант — работает, но deprecated с 3.4
var third = $('.item:eq(2)');
var firstThree = $('.item:lt(3)');
// Современный вариант — тот же результат, чистый CSS-селектор + метод
var third = $('.item').eq(2);
var firstThree = $('.item').slice(0, 3);
Отдельно стоит псевдокласс :focus — в отличие от перечисленных выше, он не deprecated и не относится к позиционным: это стандартный CSS-псевдокласс, который jQuery поддерживает как обычный проход через querySelectorAll(). Про него — в разделе «Прочие селекторы».
Фильтры потомков
Стандартные CSS-псевдоклассы для позиции элемента среди детей одного родителя — в отличие от :eq() и соседей, они не deprecated и есть в обычном CSS.
| Селектор | Что выбирает |
:first-child | Элемент, который является первым ребёнком своего родителя (совпадений в документе может быть много — по одному на каждого подходящего родителя) |
:last-child | Элемент, который является последним ребёнком своего родителя |
:only-child | Элемент — единственный ребёнок своего родителя (и первый, и последний одновременно) |
:nth-child(n) | Элемент на позиции n среди всех детей родителя, считая с 1. Принимает число, ключевые слова odd/even или формулу an+b, например :nth-child(3n+1) |
:first-of-type, :last-of-type, :only-of-type, :nth-of-type(n) | То же самое, но считают позицию только среди детей того же тега, а не среди всех детей подряд |
Разница между :nth-child() и :nth-of-type() проявляется, когда в родителе вперемешку лежат разные теги: li:nth-child(2) совпадёт, только если второй по счёту ребёнок родителя — именно li; если вторым стоит, например, служебный span, а нужный li идёт третьим, :nth-child(2) его не найдёт. li:nth-of-type(2) в той же разметке найдёт второй по счёту именно li, игнорируя остальные теги между ними.
Фильтры содержимого
Эти псевдоклассы — расширения jQuery, за исключением явно отмеченных случаев; в чистом CSS их нет.
| Селектор | Что выбирает |
:contains(text) | Элемент, в текстовом содержимом которого встречается строка text (регистрозависимо, без учёта тегов внутри). Страница :contains() |
:empty | Элемент без детей — ни элементов, ни текстовых узлов (в том числе пробельных). Страница :empty |
:has(selector) | Элемент, внутри которого есть хотя бы один элемент, подходящий под вложенный selector. Страница :has() |
:parent | Элемент, у которого есть хотя бы один дочерний узел (элемент или непустой текст) — по сути обратное к :empty |
// Найти карточки товара, где явно написано «Нет в наличии»
var outOfStock = $('.product-card:contains("Нет в наличии")');
// Найти списки, внутри которых есть хотя бы одна ссылка
var listsWithLinks = $('ul').has('a');
// то же самое через селектор:
var listsWithLinks2 = $('ul:has(a)');
:contains() ищет строго по подстроке в видимом тексте и не понимает регулярных выражений и регистронезависимости «из коробки» — для поиска без учёта регистра обычно оборачивают в .filter() с собственной функцией сравнения, а не полагаются на сам селектор.
Видимость: :visible и :hidden
Это единственная пара псевдоклассов, где формулировка «видим ли элемент» не совпадает с бытовым представлением «виден ли он глазом на экране». Официальное определение: элемент считается :visible, если у него есть layout-бокс, в том числе с нулевой шириной или высотой (уточнение действует с jQuery 3 — раньше требовалась ширина или высота больше нуля). Проще говоря, элемент с display: none (у него самого или у любого предка) — :hidden, а элемент с visibility: hidden или opacity: 0 — формально всё ещё :visible, потому что место в раскладке он не теряет.
| Селектор | Что выбирает |
:visible | Элементы, занимающие место в раскладке (в том числе с нулевыми шириной/высотой) |
:hidden | Всё остальное: display: none, элементы вне документа, а также формы <input type="hidden">. Страница :hidden |
Про цену. Официальная документация прямо предупреждает: активное использование :visible/:hidden может дорого стоить по производительности, потому что браузеру приходится пересчитывать раскладку страницы, чтобы понять, есть ли у элемента layout-бокс. В цикле по большому списку элементов или на каждый скролл/resize лучше не гонять этот селектор заново, а закешировать результат или проверять видимость точечно, для конкретного элемента, а не для всей страницы.
Ещё нюанс: элемент, не вставленный в документ (создан через $('<div>'), но не добавлен на страницу), jQuery всегда посчитает :hidden — она не может заранее знать, какие стили применятся к нему после вставки.
Набор расширений jQuery для полей ввода — исторически удобны, но почти все имеют прямой аналог на чистом CSS через атрибут type, который к тому же обычно быстрее.
| Селектор jQuery | Что выбирает | Эквивалент на CSS |
:input | input, textarea, select и button — всё, что относится к полям формы | прямого однострочного аналога нет, обычно так и оставляют. Страница :input |
:text | <input type="text"> (а также input без атрибута type — по умолчанию это текстовое поле) | input[type="text"] |
:checkbox | <input type="checkbox"> | input[type="checkbox"] — страница :checkbox |
:radio | <input type="radio"> | input[type="radio"] |
:checked | Отмеченные чекбоксы и radio, а также выбранные option | :checked — совпадает и в стандартном CSS. Страница :checked |
:selected | Выбранный option внутри select | option:checked |
:disabled | Отключённые поля (атрибут disabled) | :disabled — совпадает и в стандартном CSS. Страница :disabled |
:enabled | Все поля, кроме отключённых | :enabled |
:button | <button> и <input type="button"> | button, input[type="button"] |
:file | <input type="file"> | input[type="file"] |
:image | <input type="image"> | input[type="image"] |
// Собрать значения всех отмеченных чекбоксов формы
var selected = $('input[type="checkbox"]:checked')
.map(function () { return this.value; })
.get();
// Отключить все поля формы разом
$('#order-form :input').prop('disabled', true);
:checked и :disabled — единственные из этого списка, что совпадают со стандартными CSS-псевдоклассами один в один; остальные — расширения jQuery и в чистом CSS не существуют. Для больших форм с сотнями полей связка тег[type="..."] предпочтительнее одноимённого jQuery-псевдокласса: она уходит целиком в нативный querySelectorAll(), а :checkbox/:radio/:text и подобные требуют собственной постобработки внутри jQuery.
Прочие селекторы
| Селектор | Что выбирает |
:not(selector) | Элементы, не подходящие под вложенный selector. jQuery принимает внутри :not() в том числе собственные расширения (например, :not(:visible)), которых нет в стандартной спецификации CSS |
:header | Заголовки h1–h6. Страница :header |
:animated | Элементы, для которых в данный момент выполняется анимация методами jQuery (.animate(), .fadeIn() и т. п.). Страница :animated |
:focus | Элемент, находящийся в фокусе прямо сейчас. Стандартный CSS-псевдокласс, не deprecated |
:root | Корневой элемент документа — на практике почти всегда html |
:target | Элемент, id которого совпадает с фрагментом текущего URL (частью после #) |
:lang(code) | Элементы с указанным языком — по атрибуту lang у самого элемента или ближайшего предка |
:not(), :focus, :root, :target и :lang() — часть стандартного CSS, поэтому в чистом виде (без вложенных jQuery-расширений внутри :not()) уходят напрямую в браузерный querySelectorAll(). То же — с другими стандартными CSS-псевдоклассами уровня Selectors 4, например :is() и :where() (см. описание :is() на MDN): jQuery их не реализует сама, а передаёт всё, что не входит в список её расширений, браузеру — так что они должны сработать и через $() именно потому, что это работа браузера, а не специальная поддержка со стороны jQuery.
Производительность селекторов
На обычном сайте с сотнями элементов разница не заметна на глаз. Но для больших списков, таблиц и кода, который выполняется в цикле или на каждый скролл/resize, полезно держать в голове несколько правил.
- Селектор по id — самый быстрый.
$('#header') jQuery может отдать напрямую через быстрый путь к id-элементу, без разбора селектора как строки.
- Сужайте контекст поиска. Вместо повторного поиска по всему документу используйте
.find() на уже найденном элементе или второй аргумент $(selector, context) — это ограничивает область, в которой браузеру нужно искать совпадения.
- Кешируйте выборку в переменную, если один и тот же набор элементов используется несколько раз подряд, вместо повторных вызовов
$('.item') на каждое обращение.
- Избегайте jQuery-расширений в горячих местах.
:contains(), :has(), :visible, :checkbox и подобные не умеют пройти через нативный querySelectorAll() целиком — jQuery сначала находит более широкий набор кандидатов, а потом фильтрует их вручную. Если такой псевдокласс нужен внутри длинного селектора, официальная рекомендация — вынести его в отдельный .filter() после основного, чистого CSS-селектора: $('.list li a').filter(':contains("текст")') вместо $('.list li a:contains("текст")').
- Не гоняйте
:visible/:hidden в цикле по большому списку — каждый такой вызов может заставить браузер пересчитать раскладку страницы (см. раздел «Видимость» выше).
- Упрощайте цепочку вложенности.
$('.data td.gonzalez') обычно работает не медленнее, чем более специфичный $('.data table.attendees td.gonzalez'), а читается и поддерживается проще.
Экранирование спецсимволов
У CSS-селекторов есть свои спецсимволы — точка, двоеточие, квадратные скобки, решётка и другие. Если значение id или класса, с которым нужно построить селектор, приходит не из кода, а откуда-то извне (генератор форм, шаблонизатор, серверный id вида ctl00.item) и может содержать такие символы, собирать селектор конкатенацией строк напрямую опасно — селектор либо не сработает, либо найдёт не то. Для этого с jQuery 3.0 есть $.escapeSelector() — экранирует любой символ, имеющий особый смысл в CSS-селекторе.
// id содержит точку — как обычный CSS-селектор с классом
var fieldId = 'form.field.5';
// Не сработает как ожидается: точка внутри "#form.field.5"
// будет прочитана как начало селектора класса
// var wrong = $('#' + fieldId);
// Правильно — экранируем спецсимволы перед подстановкой в селектор
var $field = $('#' + $.escapeSelector(fieldId));
Тот же приём нужен для значений, которые пользователь вводит сам (например, поиск по data-tag из строки поиска), — экранирование защищает от случайных синтаксических ошибок в селекторе, если введённая строка содержит кавычки, скобки или другие спецсимволы.
Селекторы на чистом JS
Большинство селекторов из этой шпаргалки — обычный CSS, поэтому они один в один работают и в нативном document.querySelector()/querySelectorAll() без jQuery: document.querySelectorAll('.card[data-status="active"]') найдёт то же самое, что $('.card[data-status="active"]'). Разница начинается там, где используются jQuery-расширения — :contains(), :visible, :eq() и подобные: для них в браузере готового аналога нет, и логику приходится писать самостоятельно (например, фильтровать результат querySelectorAll через Array.from(...).filter(...)). Подробный разбор с таблицами соответствий методов, а не только селекторов, — в статье jQuery и чистый JavaScript.
Итог и чек-лист
- Всё, что jQuery принимает как CSS-селектор без собственных расширений, уходит напрямую в браузерный
querySelectorAll() — это самый быстрый путь.
:first, :last, :eq(), :gt(), :lt(), :even, :odd — deprecated с jQuery 3.4, но продолжают работать и в 3.x, и в 4.0. Для нового кода используйте методы .first(), .last(), .eq(), .slice(), .even()/.odd() (два последних — с jQuery 3.5.0).
:visible/:hidden определяются по наличию layout-бокса, а не по opacity или visibility — и стоят дороже других селекторов по производительности.
- Для форм атрибутный селектор (
input[type="checkbox"]) быстрее одноимённого jQuery-псевдокласса (:checkbox), потому что уходит в нативный querySelectorAll() целиком.
- Селектор по
[data-*] и метод .data() — не одно и то же: селектор видит только то, что реально записано в атрибуте разметки.
- Значения, которые приходят не из кода напрямую (id с точками, ввод пользователя), перед подстановкой в селектор пропускайте через
$.escapeSelector().
- В горячих участках — циклах по большим спискам, обработчиках скролла — избегайте jQuery-расширений внутри основного селектора; выносите их в отдельный
.filter() после чистого CSS-селектора или проверяйте условие точечно, для одного элемента.
Частые вопросы
Как выбрать элемент по data-атрибуту в jQuery?
Обычным CSS-селектором по атрибуту: $('[data-user-id]') — если атрибут просто должен присутствовать, или $('[data-user-id="42"]') — если важно конкретное значение. Это не то же самое, что .data('userId'): атрибутный селектор всегда читает то, что реально написано в разметке, а .data() может отдавать значение, изменённое из JS и не попавшее обратно в HTML. Подробности — в разделе «Атрибуты» выше.
Как выбрать элемент по части класса, а не по полному имени?
Через атрибутные селекторы, применённые к атрибуту class: [class*="item"] найдёт класс, содержащий «item» где угодно (в том числе как часть другого слова), а [class~="item"] — только если «item» — целое отдельное слово в списке классов через пробел. Второй вариант обычно точнее и реже даёт случайные совпадения.
Как проверить, что jQuery-селектор действительно что-то нашёл?
Через свойство .length у результата: if ($('.banner').length) { ... }. jQuery-объект — это всегда псевдомассив, даже пустой, поэтому обращение к несуществующему элементу не бросает ошибку само по себе, но операции над пустой выборкой просто ничего не делают — и без проверки .length легко не заметить, что селектор ничего не нашёл.
Чем :first отличается от :first-child?
:first — расширение jQuery: берёт первый элемент из уже найденного набора, независимо от того, где он стоит среди других детей родителя. :first-child — стандартный CSS: выбирает элемент, только если он в принципе первый ребёнок своего родителя, и таких совпадений в документе может быть много (по одному на каждого подходящего родителя). $('li:first') вернёт один элемент из всего документа, $('li:first-child') — все li, которые первые в своём ul/ol.
Почему :eq() «не работает» в новой версии jQuery?
Он по-прежнему работает и в 3.x, и в 4.0 — просто помечен как deprecated начиная с jQuery 3.4: официальная документация рекомендует заменить его методом .eq(), применённым после выборки ($('li').eq(2) вместо $('li:eq(2)')), а не переставать использовать вовсе. Если код на реальном сайте вдруг перестал находить элемент через :eq — причина не в самом селекторе, а в чём-то другом (изменилась разметка, конфликт версий jQuery, ошибка в индексе).
Как выбрать все отмеченные чекбоксы через jQuery?
$('input[type="checkbox"]:checked') — стандартная связка: атрибутный CSS-селектор сужает поиск до чекбоксов, псевдокласс :checked оставляет только отмеченные. Написать только $(':checked') тоже сработает (заодно захватит отмеченные radio и выбранные option), но связка с [type="checkbox"] быстрее и однозначнее по смыслу.
[ наверх ]