www.jQueryBook.ru - jQuery документация

 

 

 

 



Селекторы 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
:inputinput, 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 внутри selectoption: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"] быстрее и однозначнее по смыслу.

[ наверх ]









 




Справочник по jQuery JavaScript API на русском языке