Использование селекторов по атрибутам в jQuery | JavaScript. Базовый
В случае, если вам необходимо выбрать все активные поля input, либо все gif изображения на странице, или ссылки на один и тот же сайт, то обычными селекторами по классу, либо идентификатору, эту задачу не решить (если не добавлять каждому нужному элементу по классу)
Для решения этой задачи на помощь приходит такая группа селекторов, как селекторы по атрибутам, суть их очень проста, мы используем обычные селекторы по классу, id, или по названию тега и комбинируем их, указывая необходимую информацию о необходимых нам значениях их атрибутов.
Ниже приведен список основных селекторов по атрибутам, которые мы можем использовать, а то, как их применять, вы можете подсмотреть в видео-уроке
Селектор по наличию атрибута
Выбирает элемент(ы), которые содержат указаный атрибут, вне зависимости от его значения.
$("selector[attr]")
Селектор по значению атрибута
Выбирает элемент(ы), с заданным значением атрибута.=’value’]»)
Селектор по окончанию значения атрибута
Выбирает элемент(ы), которые содержат атрибут, который заканчивается на заданную строку.
$("selector[attr$='value']")
Селектор по наличию значения в атрибуте
Выбирает элемент(ы), который содержит атрибут, у которого значение содержит заданную строку.
$("selector[attr*='value']")
Селектор по наличию значения в атрибуте
Выбирает элемент(ы), который содержит атрибут, в который входит указанное слово.
$("selector[attr~='value']")
Селектор по атрибуту с префиксом
Выбирает элемент(ы), который содержит атрибут, у которого значение либо равно заданной строке, либо начинается с заданной строки с последующим дефисом.
$("selector[attr|='value']")
Селекторы атрибутов — CSS | MDN
Селекторы атрибутов отбирают элементы по наличию атрибута или его значению.=»#»] {background-color:gold} a[href$=».cn»] {color: red;} a[href*=»example»] {background-color: #CCCCCC;}
<div> <a href="http://example.com">English:</a> <span lang="en-us en-gb en-au en-nz">Hello World!</span> </div> <div> <a href="#portuguese">Portuguese:</a> <span lang="pt">Olá Mundo!</span> </div> <div> <a href="http://example.cn">Chinese (Simplified):</a> <span lang="zh-CN">世界您好!</span> </div> <div> <a href="http://example.cn">Chinese (Traditional):</a> <span lang="zh-TW">世界您好!</span> </div>
BCD tables only load in the browser
Селекторы JQuery
В jQuery, селекторы в основном позаимствованы из CSS 1-3, также добавлены свои, что дало хороший набор инструментов для манипуляций с элементами в документе.
Описание всех селекторов на api.`{|}~), то они должны экранироваться.
Например, для элемента с id="foo.bar"
, будет такой селектор $("#foo\.bar")
.
Теги, ID и классы
$("*") |
Все теги |
$("p") |
Все <p> |
$("h2,div,p") |
Все <h2> , <div> , <p> |
$(":header") |
Все заголовки <h2> , <h3> … |
$("#lastname") |
Элемент с id="lastname" |
$(".intro") |
Все элементы с
|
$(".intro,.demo") |
Все элементы с классами «intro», «demo» |
$(".intro.demo") |
Все элементы с классом «intro» и «demo» |
$(".intro .demo") |
Все элементы с классом «demo», которые находится внутри «intro» |
$("div > p") |
Все <p> , которые являются прямыми потомками <div> |
$("div p") |
Все <p> , которые являются потомками <div> |
$("div + p") |
<p> , которые идут за <div> |
$("div ~ p") |
Все <p> , которые идут за <div> , в общем родителе |
2
Атрибуты
$("[href]") |
Все элементы с атрибутом href |
$("[href][title]") |
Все элементы с атрибутами href и title |
$("[href='default.='Tom']") |
Все элементы с атрибутом title , начинающимся с «Tom» |
$("[title~='hello']") |
Все элементы с атрибутом title , содержащим определенное слово «hello» |
$("[title*='hello']") |
Все элементы с атрибутом title , содержащим слово «hello» |
3
Порядок элементов
$("p:first") |
Первый <p> |
$("p:last") |
Последний <p> |
$("tr:even") |
Четные
|
$("tr:odd") |
Нечетные <tr> |
Поиск в родителе
$("div p:first-child") |
Первый <p> в <div> |
$("div p:first-of-type") |
Первый <p> в <div> , игнорируя другие элементы |
$("div p:last-child") |
Последний <p> в <div> |
$("div p:last-of-type") |
Последний <p> в <div> , игнорируя другие элементы |
$("div p:nth-child(2)") |
Второй <p> в <div> |
$("div p:nth-last-child(2)") |
Второй с конца <p> в <div> |
$("div p:nth-of-type(2)") |
Второй <p> в <div> , игнорируя другие элементы |
$("div p:nth-last-of-type(2)") |
Второй с конца <p> в <div> |
$("div p:only-child") |
<p> , который является единственным потомком в <div> |
$("div p:only-of-type") |
<p> , который является единственным потомком в <div> , игнорируя другие элементы |
Поиск по индексу (индекс элементов начинается с нуля)
$("ul li:eq(3)") |
Четвертый <li> в списке <ul> |
$("ul li:gt(3)") |
Все <li> с индексом > 3 |
$("ul li:lt(3)") |
Все <li> с индексом < 3 |
4
Состояние элементов
$(":animated") |
Элементы, которые находятся в процессе анимации |
$(":focus") |
Элемент в фокусе |
$(":contains('Hello')") |
Все теги, содержащие текст «Hello» |
$("div:has(p)") |
Элементы <div> , которые содержат хотя бы один элемент <p> |
$(":empty") |
Пустые элементы |
$(":not(:empty)") |
Непустые элементы |
$(":parent") |
Все элементы, у которых есть хотя бы один дочерний элемент или текст |
$("p:hidden") |
Скрытые элементы <p> (display: none; ) |
$("p:visible") |
Видимые элементы <p> |
$(":root") |
Выбирает элемент, который является корнем документа (<html> ) |
$("p:lang(ru)") |
Выбирает все элементы c указанным языком <p lang="ru">...</p> |
5
Поля форм
$(":input") |
Все поля input |
$(":text") |
Текстовые поля type="text" |
$(":password") |
Поля с паролем type="password" |
$(":radio") |
Радиокнопки |
$(":checkbox") |
Чекбоксы |
$(":submit") |
Кнопки с type="submit" |
$(":reset") |
Кнопки с type="reset" |
$(":button") |
Кнопки с type="button" |
$(":image") |
Кнопки с type="image" |
$(":file") |
Выбор файла type="file" |
Состояние полей
$(":enabled") |
Все активные элементы (без disabled="disabled" ) |
$(":disabled") |
Заблокированные элементы |
$(":selected") |
Выбранные <option> в <select> |
$(":checked") |
Отмеченные чекбоксы и радиокнопки |
Селекторы по атрибутам в CSS
Селекторы по атрибутам в CSS
В CSS существует возможность обратиться к элементам html-документа по значению его атрибутов. Вы, конечно, уже знаете про ID и классы. Давайте взглянем на следующий html:
<h3 rel="friend">David Walsh</h3>
У этого элемента три атрибута: id, class и rel. Обратиться к этому элементу в CSS вы можете либо по его идентификатору (#first-title), либо по имени класса (.magical). Однако знали ли вы, что вы также можете обратиться к нему, используя атрибут rel? Это и называется селекторы по атрибутам:
h3[rel=friend] {
/* woohoo! */
}
Существует множество вариантов их использования. Давайте разберёмся более детально с различными опциями и попытаемся придумать сценарии использования атрибутов в реальной жизни.
[rel=external]
Атрибут точно соответствует заданному значению
В приведённом выше примере, атрибут элемента h3 был равен «friend». Селектор, который мы написали ссылался на него, поскольку значение атрибута точно равно «friend». Именно точное. Давайте посмотрим на другой пример:
<h2 rel="external">Attribute Equals</h2>
h2[rel=external] { color: red; }
Более реальный пример — стилизация блогролла (blogroll). Скажем у вас есть список ссылок на дружественные сайты:
<a href="http://perishablepress.com">Jeff Starr</a>
<a href="http://davidwalsh.name">David Walsh</a>
<a href="http://accidentalninja.net/">Richard Felix</a>
И вы хотите задать каждой ссылке свой стиль. Традиционный подход состоит в том, что каждой ссылке указывается класс, но этот подход требует дополнительной разметки. Другой способ — это использование псевдоселектора nth-child. Однако этот подход требует определённого порядка элементов. Эта проблема идеально подходит для применения селекторов по атрибутам, поскольку ссылки уже являются уникальными.
a[href=http://perishablepress.com] { color: red; }
Я уверен, что наиболее часто этот тип селектора используется для элементов input (text, radio и т.п.). Все эти элементы сильно отличаются друг от друга, и писать что-нибудь типа input { padding: 10px; } в большинстве случаев не лучшая идея. Гораздо чаще используется следующая запись:
input[type=text] { padding: 3px; }
input[type=radio] { float: left; }
Это единственный способ стилизовать элементы input без дополнительной разметки и всяческих ухищрений.
[rel*=external]
Атрибут содержит заданное значение.
Теперь начинаются более интересные вещи. Знаку равенства в селекторе по атрибуту может предшествовать другой знак, который меняет назначение его использования. Например, «*=» означает «заданное значение может находиться где угодно в значении указанного атрибута». Взгляните на следующий пример:
<h2 rel="xxxexternalxxx">Attribute Contains</h2>
h2[rel*=external] { color: red; }
Не забывайте, что идентификаторы и классы — это тоже атрибуты и вы можете их в селекторах по атрибутам. Итак, давайте предположим, что вы пишете CSS для сайта, в котором вы не имеете доступа к разметке, а неопытный разработчик оставил вам такое:
<div></div>
<div></div>
<div></div>
Вы можете подсветить все эти элементы следующим образом:
div[id*=post] { color: red; }
[rel^=external]
Атрибут начинается с заданного значения
<h2 rel="external-link yep">Attribute Begins</h2>
h2[rel^=external] { color: red; }
Пример из жизни может быть такой: скажем вам необходимо подсветить ссылки на дружественный вам сайт отличным от остальных ссылок цветом.=http://perishablepress.com] { color: red; }
[rel$=external]
Атрибут заканчивается на заданное значение
Если есть возможность сделать выбор по началу значения атрибута, то почему не быть и обратной возможности?
<h2 rel="friend external">Attribute Ends</h2>
h2[rel$=external] { color: red; }
Честно говоря, я не смог найти реального примера применения такого вида селектора. Но я верю что он существует. Предположим, что вам необходимо подсветить ссылки, которые заканчиваются не значимыми символами:
a[href$=#], a[href$=?] { color: red; }
[rel~=external]
Атрибут находится в списке, разделённом пробелами
Как вы уже знаете, вы можете указать несколько классов стилей для одного элемента. И если вы делаете именно так, то вы можете использовать имя класса для доступа к элементу в CSS. В случае использования селекторов по атрибуту, не всё так просто. Если атрибуту rel присвоено несколько значений (разделённых пробелами), то вам необходимо использовать «~=»;
<h2 rel="friend external sandwich">Attribute Space Separated</h2>
h2[rel~=external] { color: red; }
Вы можете подумать, почему бы нам не использовать в этом случае «*=» ? Действительно, такой вариант использования более гибок, однако он может быть слишком гибок. Рассматриваемый селектор требует, чтобы значение отделялось пробелом, а «*=» — нет. Таким образом, если у вас есть два элемента (один с rel=home friend-link, а второй с rel=home friend link), то вам необходимо использовать селектор для случая с пробелами, чтобы выбрать только второй элемент.
[rel|=external]
Атрибут находится в списке, разделённом дефисами
Список, разделённый дефисами очень похож на описанный выше список разделённый пробелами. Но опять же есть свои особенности перед использованием селектора с «*=».=Important] { color: red; }
Поддержка браузерами
Каждый пример, приведённый выше, работает во всех современных браузерах: Safari, Chrome, Firefox, Opera и IE7 и выше.
Селектор | Пример | Описание |
---|---|---|
.class | .intro | Выделяет все элементы с |
#id | #firstname | Выделяет все элементы с |
* | * | Выделяет все элементы |
элемент | p | Выделить все элементы <p> |
элемент,элемент | div, p | Выделить все элементы <div> и <p> |
элемент элемент | div p | Выделить все элементы <p> внутри элементов <div> |
элемент>элемент | div > p | Выделить все элементы <p> где родителем является элемент <div> |
элемент+элемент | div + p | Выделить все элементы <p> которые размещаются сразу после элементов <div> |
элемент1~элемент2 | p ~ ul | Выделить каждый элемент <ul> которые размещаются сразу перед элементом <p> |
[атрибут] | [target] | Выделяет все элементы с атрибутом target |
[атрибут=значение] | [target=_blank] | Выделяет все элементы с target=»_blank» |
[атрибут~=значение] | [title~=flower] | Выделяет все элементы с атрибутом title, содержащие слово «flower» |
[атрибут|=значение] | [lang|=en] | Выделяет все элементы со значением атрибута lang, начиная с «en» |
[атрибут^=значение] | a[href^=»https»] | Выбирает каждый элемент <a>, значение атрибута href который начинается с «https» |
[attribute$=значение] | a[href$=».pdf»] | Выбирает каждый элемент <a>, значение атрибута href который заканчивается на «.pdf» |
[атрибут*=значение] | a[href*=»schoolsw3″] | Выбирает каждый элемент <a>, значение атрибута href которого содержит подстроку «schoolsw3» |
:active | a:active | Выбор активной ссылки |
::after | p::after | Вставляет что-нибудь после содержимого каждого элемента <p> |
::before | p::before | Вставить что-то перед содержимым каждого элемента <р> |
:checked | input:checked | Выбирает каждый проверенный элемент <input> |
:disabled | input:disabled | Выбрать каждый отключенный элемент lt;input> |
:empty | p:empty | Выбирает каждый элемент <p>, у которого нет дочерних элементов (включая текстовые узлы) |
:enabled | input:enabled | Выбирает каждый включенный элемент <input> |
:first-child | p:first-child | Выбирает каждый элемент <p>, который является первым дочерним элементом родительского элемента |
::first-letter | p::first-letter | Выбирает первую букву каждого элемента <p> |
::first-line | p::first-line | Выбирает первую строку каждого элемента <p> |
:first-of-type | p:first-of-type | Выбирает каждый элемент <p>, который является первым элементом <p> своего родителя |
:focus | input:focus | Выбирает элемент ввода, имеющего фокус |
:hover | a:hover | Выделяет ссылки при наведении курсора мыши |
:in-range | input:in-range | Выделяет входные элементы со значением в заданном диапазоне |
:invalid | input:invalid | Выбирает все входные элементы с недопустимым значением |
:lang(language) | p:lang(it) | Выбирает каждый элемент <p> с атрибутом lang, равным «it» (итальянский) |
:last-child | p:last-child | Выбирает каждый элемент <p>, который является последним дочерним элементом родительского элемента |
:last-of-type | p:last-of-type | Выбирает каждый элемент <p>, который является последним элементом <p> своего родителя |
:link | a:link | Выделяет все непосещенные ссылки |
:not(selector) | :not(p) | Выбирает каждый элемент, который не является элементом <p> |
:nth-child(n) | p:nth-child(2) | Выбирает каждый элемент <p>, который является вторым дочерним элементом родительского элемента |
:nth-last-child(n) | p:nth-last-child(2) | Выбирает каждый элемент <p>, который является вторым дочерним элементом родительского элемента, считая от последнего дочернего элемента |
:nth-last-of-type(n) | p:nth-last-of-type(2) | Выбирает каждый элемент <p>, который является вторым элементом <p> своего родителя, считая от последнего потомка |
:nth-of-type(n) | p:nth-of-type(2) | Выбирает каждый элемент <p>, который является вторым элементом <p> своего родителя |
:only-of-type | p:only-of-type | Выбирает каждый элемент <p>, который является единственным элементом <p> родительского элемента |
:only-child | p:only-child | Выбирает каждый элемент <p>, который является единственным дочерним элементом родительского элемента |
:optional | input:optional | Выбирает элементы ввода без атрибута «required» |
:out-of-range | input:out-of-range | Выбирает входные элементы со значением вне указанного диапазона |
:read-only | input:read-only | Выбирает входные элементы с указанным атрибутом «readonly» |
:read-write | input:read-write | Выбирает входные элементы с не указанным атрибутом «readonly» |
:required | input:required | Выбирает входные элементы с указанным атрибутом «required» |
:root | :root | Выбирает корневой элемент документа |
::selection | ::selection | Выделяет часть элемента, выбранную пользователем |
:target | #news:target | Выбирает текущий активный элемент #news (при щелчке по URL, содержащему имя привязки) |
:valid | input:valid | Выбирает все входные элементы с допустимым значением |
:visited | a:visited | Выбирает все посещенные ссылки |
Noveo Блог • Краткий ликбез по локаторам в вебе
«Любишь UI-автотесты писать, люби и локаторы подбирать.» (с) Конфуций
Конфуций, конечно, был мудрым человеком и еще поговаривал, что знание локаторов пригождается не только тем, кто работает с автоматизацией клиентской части.
Зачем это мне?
🔹 Если вы можете быстро найти локатор элемента, то репортить баги UI-части становится в разы проще. Вместо того, чтобы искать «красную кнопку ОК на странице авторизации пользователя в личный кабинет», разработчик вбивает в поиск «.btn.submit» и моментально находит элемент, для которого нужно сделать исправления.
🔹 Если вы знаете, как работают CSS-селекторы, то можете проверять работу визуальной части не только как пользователь, но и как… скажем, продвинутый пользователь. Например, обнаружить, что выполненный пункт в ToDo-листе не перечеркивается, потому что не подтянулся стиль, который отвечает за то, чтобы текст элемента, находящегося в определенном состоянии, был зачеркнут.
🔹 Вообще механика работы веба — того, что мы, собственно, тестируем — становится намного понятнее, а работать с тем, что понимаешь, в разы приятнее. Кроме того, появляются новые идеи для проверок: а что будет, если мы уберем вот этот атрибут и попробуем ввести в поле невалидное значение? А если у кнопки стереть ‘disabled‘ и кликнуть на нее, что-то произойдет?
🔹 Можно открывать новые для себя направления деятельности: например, одна моя коллега не пишет UI-тесты, но редактирует код страниц и добавляет элементам data-test-* атрибуты. Это требует аналитического мышления, системного подхода и внимательности, а ещё позволяет поработать с кодом, но без написания автотестов (если вдруг вам их писать не очень хочется).
Короче, локаторы нужны и важны, а DevTools (F12 в большинстве браузеров) — наш лучший друг.
Что такое локаторы?
По сути — запросы с тем или иным синтаксисом, которые позволяют нам обращаться к элементам страницы по их уникальным (или не очень) характеристикам.
То есть если обычно вы видите кнопку «Login» и знаете, что надо нажать именно на нее, то в случае с автоматизацией браузеру надо дать команду «нажать», а еще обозначить, что именно жать. Собственно, чтобы взаимодействие браузера происходило с нужным вам элементом, а не соседним или вообще скрытым, и нужно умение писать уникальные локаторы. Еще хорошо, чтобы локаторы были читабельными — тогда вашим коллегам будет проще понимать, к чему именно вы обращаетесь (и что пошло не так в случае проблемы), но это уже, увы, не всегда зависит от QA.
Какие виды локаторов существуют?
Selenium WebDriver ищет элементы с помощью двух методов:
- Find Element
- Find Elements
Оба получают на вход параметры: объект класса By + тип запроса (по чему будем искать элемент) и сам локатор. Локатор должен соответствовать типу запроса: если ищем по атрибуту, то в локатор кидаем значение атрибута, если по СSS-селектору — то селектор. Если запрос будет вида
find_element(By.XPATH, "#login_form")
, то, разумеется, вместо рабочего теста мы получим ошибку.
Пара других различий, которые важно знать о методах Find Element и Find Elements:
Различия методов Find Element и Find ElementsОбъект класса By может принимать на вход следующие виды локаторов:
- ID
- Name
- XPath
- Link text
- Partial link text
- Tag name
- Class name
- CSS selector
При этом ID, Name, Tag name и Class name — частные случаи CSS-селекторов. Таким образом, основные виды локаторов, с которыми мы будем сталкиваться — это CSS-селекторы и XPath. О них и поговорим ниже.
CSS Selector
Использует для поиска элемента его части (атрибуты). Изначальная цель использования — поиск элементов HTML-странички и навешивание на них стилей. Так как стилями нужно мочь обвешать все элементы страницы, синтаксис селекторов разработан с ориентиром на максимальную гибкость.
Синтаксис:
- id (#uniqueid)
- tag (h2)
- name ([name=»my-element»])
- class (.class1.class2)
- другое значение атрибута ([attribute=»value»])
- текст в элементе: псевдокласс из jquery :contains()
- положение потомка: :nth-child(1)
Примеры использования:
#test
— поиск по ID «test»tag
— поиск по тэгу «tag».my-class
— поиск по классу «my-class».class1.class2
— поиск по классам «class1 class2» или «class2 class1» (обратите внимание, что порядок классов элемента не имеет значения при написании селектора)[name="my-name"]
— поиск по имени «my-name»[attribute="value"]
— поиск по значению «value» атрибута «attribute»a:contains("test")
— поиск по тексту «test», который содержится в элементе#posts > .item:nth-child(2) > .title
— составной селектор. Ищет элемент с классом title, который является потомком второго потомка элемента с классом item, который, в свою очередь, потомок элемента с ID = posts.
XPath
Поиск элемента(ов) с помощью запроса XPath (XML path) — языка разметки в XML-документе. Приятный момент работы с XPath: здесь, в отличие от селекторов, можно производить перемещение как в глубину DOM-иерархии, так и в обратную сторону (например, искать родительский элемент по дочернему).
Синтаксис:
- / — поиск прямого потомка
- // — поиск потомка любой степени
- [ ] — фильтрация
- Функция text() — поиск по тексту элемента
- Функция contains() — поиск полного или частичного совпадения
- Булевы операции and, or, not
- * — выбор всех элементов
Важный момент: XPath регистрозависим. То есть если запрос вида //*[@class=”my-class”]
находит элемент, то запрос вида //*[@Сlass=”my-Сlass”]
тот же элемент не обнаружит.
Возможный вид запроса:
//корень(конкретный или *)/потомок[параметры фильтрации]
Примеры использования:
//*[@class=”my-class”]
— поиск по всем элементам, у которых есть класс «my-class».//div/p/a[text()=”Пример текста”]
— поиск по всем элементам a, содержащим текст «Пример текста» и являющимся прямыми потомками элемента p, который прямой потомок элемента div.//*[@data-test=”select-button” or contains(@class, “login-button”)]
— поиск по всем элементам, у которых есть data-test-атрибут со значением «select-button» ИЛИ у которых в имени класса есть «login-button».//div[1]
— выбор первого потомка элемента div.
DevTools — наш друг
Чтобы искать элементы быстрее и убедиться, что написанный запрос вернет нам нужное количество элементов страницы, можно (и нужно) использовать DevTools. Они открываются по нажатию F12 или комбинации Ctrl+Shift+I. Во вкладке Elements можно посмотреть код страницы и скопировать уникальный локатор того или иного элемента. Еще пару лет назад таким образом возвращались трудночитаемые монстры, но браузеры умнеют (как и мы), и теперь часто Chrome возвращает отличные лаконичные локаторы.
Селекторы и локаторы можно искать и проверять через DevToolsКак же овладеть искусством поиска красивых локаторов? Практика, практика, практика!
Почитать (и потренироваться) дополнительно можно вот тут:
1. На официальном сайте Selenium.
2. В документации к Selenium для вашего языка программирования. Вот так выглядит вариант для Python: https://selenium-python.readthedocs.io/locating-elements.html
3. В других местах:
4. С готовыми подсказками по CSS-селекторам, XPath и многому другому интересному 😉
Если вы хотите лишний раз попрактиковаться в написании CSS-селекторов — часто используемых локаторов, — рекомендуем вам заглянуть на https://www.w3schools.com/css/exercise.asp и https://flukeout.github.io/.
Тем, кому совсем интересно и хочется больше практики из реальной жизни, поможет вот такое нетрудное упражнение:
- Выбрать туториал с любой формой из раздела Forms W3Schools (например, первый — Login Form).
- На странице туториала кликнуть кнопку Try it yourself.
- Скопировать код из левой части редактора и сохранить на вашем компьютере в формате HTML.
- Открыть сохраненную HTML-страницу и поискать для каждого элемента разного рода атрибуты и тэги.
А ещё очень рекомендуем обратить внимание на шаги 1.4 — 1.6 курса Автоматизация тестирования с помощью Selenium и Python и на модули 5 и 6 курса Веб-разработка для начинающих: HTML и CSS.
Когда вы чувствуете, что готовы попробовать поиск и написание локаторов на реальном веб-сайте, вы можете использовать песочницы из вот этого поста или что-то из списка ниже:
Надеюсь, этот ликбез оказался вам полезен! Всем интересных задач и красивых локаторов 🙂
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Селекторы и производительность. Часть 1 | WebHiTech
Артемий Ломов
Поскольку волею случая ваш покорный слуга уже несколько раз выступал с докладами на тему, обозначенную в заголовке, созрела идея обстоятельно рассмотреть этот аспект в статье (точнее, похоже, даже в небольшой серии статей), уделив должное внимание задававшимся слушателями вопросам.
Попытаемся описать «сферический в вакууме» сценарий обработки CSS-правил браузером. Подчеркну, для начала обсудим именно что «сферический в вакууме», то есть классический, эталонный, теоретический сценарий. На практике реальные браузеры дополнительно оптимизируют те или иные составляющие процесса, значительно отличаясь друг от друга многочисленными индивидуальными особенностями. Об этом побеседуем предметно, с тестами на руках, несколько позже.
Справа налево!
Для каждого текущего обрабатываемого элемента HTML-разметки браузер последовательно проверяет применимость всех относящихся к данному HTML-документу CSS-правил, разбирая селекторы в направлении справа налево. Рассмотрим для определенности пример:
.content ul li {…}
Встречая CSS-правило, начинающееся таким селектором, браузер сперва проверяет, является ли текущий обрабатываемый элемент пунктом списка (li
).
Если ответ — «нет», обработка данного CSS-правила завершается. Разумеется, оно не применяется к текущему элементу. Браузер переходит к обработке следующего CSS-правила (или же следующего элемента HTML-разметки, если для текущего элемента проверена применимость всех имеющихся правил, то есть данное правило было последним в очереди).
Если же ответ — «да», браузер следует вверх по DOM-дереву в поисках элемента ul
с целью проверить, является ли наш пункт списка (li
) потомком какого-либо неупорядоченного списка (ul
).
Дальше события развиваются аналогичным образом. Если упомянутое условие вложенности элементов выполняется, браузер следует еще выше по дереву DOM, проверяя, является ли этот список (ul
) потомком некоего элемента с классом content
.
Как видим, обработка рассмотренного в нашем примере селектора может быть сопряжена со значительным количеством достаточно сложных проверок.
Кто самый быстрый?
Вполне очевидно, что наиболее предпочтительным с точки зрения производительности является использование селекторов, требующих минимального количества проверок, причем проверок самых простых. Как вы понимаете, в первую очередь под это описание подходят простые селекторы по идентификатору и по классу:
#intro {…}
.content {…}
В рамках «сферической в вакууме» модели с такими селекторами вполне сравнимы простые селекторы по типу элемента («по тегу»), например:
div {…}
Теоретически в данном случае на производительность обработки CSS-правил (но не собственно селекторов) может повлиять тот факт, что HTML-документы обычно содержат большее количество элементов какого-то определенного типа (например, div
), чем элементов с каким-либо одним заданным классом. Ну, а элемент с конкретным идентификатором по природе своей может быть вообще лишь единственным в пределах всей страницы — в противном случае код разметки будет невалидным. Можно сформулировать общее правило — при прочих равных условиях более предпочтительным с точки зрения производительности оказывается применение селекторов с большей специфичностью.
Поведение некоторых распространенных в реальном мире браузеров несколько отличается от «теоретически рассчитанного». При прочих равных простые селекторы по идентификаторам и по классам обрабатываются практически во всех браузерах одинаково быстро — разница в скорости не превышает статпогрешности. А вот простые селекторы по типу элементов обрабатываются порой заметно медленнее, даже в случае «лабораторных» тестовых примеров, когда все остальные условия специально сохраняются полностью идентичными.
Это наталкивает на мысль, что производители браузеров дополнительно оптимизируют обработку селекторов по идентификаторам и по классам. По всей видимости, для CSS-правил с такими селекторами строится нечто вроде индексов, использующихся в СУБД для ускорения доступа к отдельным записям. Разумеется, достоверно установить этот факт позволит только исследование исходного кода браузерных движков, что не входит в компетенцию и задачи автора.
Так или иначе, практика использования в CSS-коде только простых селекторов по классам и никаких более, сложившаяся в рамках парадигмы верстки независимыми блоками (включая, разумеется, разработку с применением методологии БЭМ), имеет под собой веские основания в том числе и с точки зрения производительности.
От быстрых к медленным. Простые селекторы
Итак, если бескомпромиссная производительность критически важна, можно порекомендовать ограничиться исключительно применением простых селекторов по идентификаторам и по классам, но ведь спецификации CSS дразнят веб-разработчиков несравненно более богатым выбором селекторов. Более того, этот «ассортимент» существенно дополнился разнообразными «вкусными» новшествами в спецификациях селекторов третьего и четвертого уровней. (Напомню, Selectors Level 3 — уже почти год как стабильная рекомендация W3C, полностью реализованная к настоящему моменту во всех приличных браузерах, а Selectors Level 4 — активно разрабатываемый черновик, некоторые части которого уже начинают получать экспериментальную поддержку.) Если звезды зажигают более ресурсоемкие селекторы все же существуют, значит, это кому-нибудь нужно?..
Разумеется, их вполне можно использовать в реальной практике, только подходить к делу следует с умом. Понимание того, как браузер анализирует селекторы, поможет не допустить глупостей на ранних стадиях работы над проектом и избежать необходимости в будущем переделывать «тормознутый» сайт с нуля.
Обсудим некоторые другие, более «медленные», чем перечисленные выше, простые селекторы. Попытаемся ранжировать их в порядке снижения производительности, обусловленного возрастанием количества всевозможных проверок и/или их усложнением.
Универсальный селектор (селектор-«звездочка») обладает наименьшей возможной специфичностью (0
). Поэтому обработка CSS-правила, начинающегося с такого селектора, отнимет объективно больше времени, чем обработка правила, предваряемого селектором по типу элемента (при прочих равных условиях, конечно). CSS-правило, начинающееся селектором-«звездочкой», будет применяться буквально к каждому элементу документа:
* {…}
Еще больше ресурсов отнимет обработка CSS-правила с селектором по атрибуту:
[title] {…}
В данном случае для каждого элемента HTML-документа будет проверяться наличие атрибута title
— только при соблюдении данного условия правило окажется применимым к элементу.
Как вы понимаете, селекторы по значениям атрибутов еще менее эффективны. Из всех их разновидностей наиболее «медлителен» селектор, требующий проверки вхождения подстроки в значение атрибута (такой вид селекторов впервые появился, кстати, только в CSS3):
[title*="foo"] {…}
Также крайне «медленным» будет простой селектор, использующий динамический псевдокласс:
:hover {…}
В данном случае в отношении любого элемента HTML-документа будет осуществляться проверка, не наведен ли на него курсор мышки, при выполнении всякой операции пересчета, затрагивающей данный элемент.
Уточнения на пользу и во вред
Простые селекторы, перечисленные в предыдущем разделе, на практике используются редко. (За исключением, возможно, «звездочки», которой зачастую начинают CSS-правило, обнуляющее значения свойств margin
, padding
и border
, по умолчанию отличные от нуля для некоторых элементов. Речь идет о так называемом «ластике», вместо которого предпочтительнее использовать более деликатный reset.css, рекомендованный Эриком Мейером — мы уже упоминали такую деталь в одной из предыдущих статей.) Как правило, эти синтаксические конструкции чаще применяются не сами по себе, а в составе последовательностей простых селекторов наподобие img[title]
или a:hover
. Подобные уточнения увеличивают специфичность соответствующих селекторов по сравнению с простыми селекторами [title]
и :hover
и сокращают время обработки относящихся к ним CSS-правил за счет существенного ограничения множества элементов, в отношении которых должны производиться сложные ресурсоемкие проверки.
Тем не менее, дополнительные уточнения не всегда полезны, а иногда и вовсе вредны. В частности, нет никакого смысла заменять простой селектор по идентификатору #intro
на последовательность, скажем, header#intro
. Элемент с соответствующим идентификатором в любом случае может быть лишь единственным во всем HTML-документе — иначе разметка окажется невалидной. Совершенно незачем требовать от браузера осуществления абсолютно лишней дополнительной проверки — принадлежит ли элемент с заданным идентификатором (intro
) какому-то конкретному типу (header
).
Сказанное почти полностью справедливо и для простых селекторов по классу. Скажем, нет никакого смысла употреблять последовательность вида ul.navigation
вместо простого селектора .navigation
. Или, точнее, если такой смысл появляется — значит, скорее всего, со стилем кодирования что-то не в порядке. Грамотные веб-разработчики назначают имена классам осознанно, в соответствии с четкими правилами внутренней организации кода, стараясь ни в коем случае не допускать ситуаций, когда один и тот же класс мог бы быть назначен нескольким совершенно различным по смысловой нагрузке элементам. (Мы уже затрагивали похожую проблему, обсуждая уровни семантики.)
От быстрых к медленным. Комбинированные селекторы
От простых селекторов и их последовательностей перейдем к селекторам комбинированным, по традиции постаравшись обоснованно рассортировать наиболее характерные случаи в порядке снижения эффективности использования.
Очевидно, из всех типов часто используемых на практике комбинированных селекторов, описанных в спецификациях CSS ранних уровней, наиболее «шустрым» будет такой:
h2 + p {…}
В данном случае для каждого элемента p
требуется произвести одну сравнительно несложную проверку — предшествует ли ему непосредственно элемент h2
.
Вот такой комбинированный селектор отнимет, при прочих равных, чуть больше ресурсов:
ul > li {…}
Здесь потребуется в отношении каждого элемента li
произвести проверку, является ли его родителем (то есть непосредственным предком, располагающимся внутри DOM строго на один уровень выше) некоторый элемент ul
.
Селектор, использующийся в нижеследующем правиле, при прочих равных отнимет еще большее количество ресурсов:
pre code {…}
Тут браузеру надлежит в отношении всякого элемента code
выяснить, не является ли его предком (находящимся на каком угодно более высоком уровне иерархии внутри DOM) какой-либо элемент pre
. В худшем случае для констатации неприменимости CSS-правила браузеру потребуется дойти при продвижении вверх по дереву DOM до уровня элемента body
.
Чем меньше звеньев, тем надежнее цепь
Читателю уже, полагаю, вполне очевидно, что при использовании комбинированных селекторов необходимо всячески воздерживаться от соблазна использовать более одного комбинатора на каждый такой селектор.
Иногда в CSS-коде вполне реальных проектов можно встретить конструкции наподобие таких:
body ul.navigation li a {…}
Возможно, их авторы считают, что максимально точное описание «области действия» селектора увеличит скорость обработки соответствующего CSS-правила браузером. Полагаю, что уже не требуется объяснять, что такая точка зрения ошибочна. Селектор из вышеприведенного примера вполне можно сократить до такого:
.navigation a {…}
Упоминание body
не нужно по той причине, что, как мы уже говорили, браузер сразу же, вне зависимости от наличия или отсутствия в коде разметки обрабатываемого HTML-документа соответствующих тегов, создает внутри DOM элементы html
и body
, и все элементы, использующиеся для структурирования контента, в любом случае считает вложенными внутрь body
. Так что упоминание этого элемента в составе комбинированного селектора в лучшем случае никак не повлияет ни на что, включая производительность.
(С точки зрения буквы спецификаций HTML 4.01 и HTML5 пара тегов <body>
и </body>
не является обязательной для построения минимального валидного документа. Ну, это так, к слову — лучше забудьте… Элемент уровня body
имеет смысл упоминать в составе CSS-селекторов разве что только в том случае, если ему назначен какой-либо идентификатор или класс с целью обеспечения различий в «глобальных» стилях для разных страниц сайта — но, как вы понимаете, достаточно только указания имени этого самого идентификатора или класса, тогда как упоминание всуе типа элемента является откровенно излишним.)
Упоминание ul
, кажется, уже успели обсудить выше.
Упоминание li
не нужно, поскольку в приличном HTML-коде элементы ul
всегда содержат внутри себя элементы li
в качестве непосредственных потомков, и все то, что вложено внутрь li
, автоматически вложено и внутрь ul
.
Целевые объекты селектора
Крайняя правая часть комбинированного селектора имеет особое значение. Она определяет целевые объекты селектора — the subjects of a selector. (Ссылка указывает на соответствующий фрагмент черновика спецификации Selectors Level 4, в которой этим самым целевым объектам выделен обособленный раздел — но сам по себе термин впервые определен еще в CSS2, разве что более сжато.)
Для лучшего понимания обсуждаемой сущности приведем такой пример.
.content pre code {…}
Целевыми объектами данного селектора являются элементы code
(что определяется крайней справа составляющей комбинированного селектора, ага).
Это означает, что применительно к любому HTML-документу наше CSS-правило может повлиять только на элементы типа code
. Да, в предельном случае это будут вообще все имеющиеся в структуре конкретного документа элементы code
. Но, в то же самое время, данное CSS-правило при любом возможном раскладе никак не сможет затронуть никакие другие элементы какого бы то ни было документа помимо элементов типа code
.
Авторами черновика Selectors Level 4 предложен механизм, который позволил бы веб-разработчикам переопределять целевые объекты селекторов. Непосредственно в спецификации приводится следующий пример. Вот такое CSS-правило предсказуемо будет применяться к элементам li
, являющимся единственными прямыми потомками некоторых элементов ol
:
ol > li:only-child {…}
Если же слегка модифицировать наш селектор, относящееся к нему CSS-правило будет применяться к элементам ol
, имеющим по одному дочернему элементу li
:
ol! > li:only-child {…}
(Авторы спецификации, если верить самой свежей на момент написания статьи версии ее редакторского черновика, остановились на восклицательном знаке, но прежде на его роль претендовали также символ доллара и вопросительный знак.)
Два селектора, приведенные выше, связаны с одним и тем же подмножеством структуры DOM-дерева, но имеют различные целевые объекты. Во втором случае целевыми объектами селектора являются все элементы ol
.
Описанный механизм призван реализовать функциональность давно запрошенного профессиональным сообществом веб-разработчиков селектора родительского элемента (аналогичного селектору has(…)
, имеющемуся в jQuery). Наверное, нам тут нет смысла описывать, почему это будет работать медленно в случае честной реализации в браузерах — на эту тему есть исчерпывающая статья Джонатана Снука, переведенная на русский язык. Отметим лишь то, что предложенная авторами черновика Selectors Level 4 концепция, несомненно, отличается большей гибкостью, и ее применимость выходит далеко за рамки предназначения селектора родителя.
Напоследок рассмотрим пару насущных вопросов, напрямую связанных с целевыми объектами селекторов.
Равнение направо!
В рамках разобранного нами классического сценария обработки CSS-селекторов крайняя справа часть комбинированного селектора весьма существенно влияет на производительность. Скажем, вот такое будет работать очень медленно:
#intro * {…}
Тут не следует обольщаться наличием простого селектора по уникальному идентификатору где-то в составе комбинированного селектора (слева или в серединке). Браузеры, обрабатывающие селекторы по сценариям, близким к классическому, будут для каждого элемента HTML-документа осуществлять проверку вложенности данного элемента внутрь некоего элемента с идентификатором intro
.
Заметьте, «каждый элемент» в данном случае — это как раз и суть целевые объекты нашего селектора.
Конечно, в ряде браузеров осуществляется дополнительная оптимизация производительности обработки селекторов, выходящая за рамки эталонного сценария. Согласно наблюдениям и тестам, можно сделать вывод о том, что некоторые браузеры, столкнувшись с простым селектором по идентификатору или классу где-либо в составе комбинированного селектора при анализе последнего, изменяют направление обхода DOM-дерева или же добавляют соответствующие правила в гипотетический «индекс». Но все же следует учитывать, что далеко не все браузеры ведут себя столь «интеллектуально». В ходе реальной практики веб-разработки имеет смысл всегда ориентироваться на наихудший вариант — обработку браузерами селекторов по классическому сценарию без дополнительной внутренней оптимизации.
Крайняя справа часть комбинированного селектора сразу же жестко ограничивает подмножество элементов HTML-документа, к которым в принципе может быть применено соответствующее CSS-правило — и, как следствие, подмножество элементов, в отношении которых будут осуществляться дополнительные ресурсоемкие проверки в процессе установления применимости правила. Воистину, грех этим не пользоваться. По крайней мере, грех ставить «звездочку» на столь почетное правое место. 🙂
Часто задают вопрос: как влияют на производительность селекторы, в составе которых упоминаются элементы, не использующиеся в данном конкретном HTML-документе? Являют ли собой соответствующие CSS-правила нечто большее, чем просто лишние килобайты данных, передаваемых по каналу связи?
В рамках пристально рассмотренного нами классического сценария все будет зависеть от того, в каком контексте в составе селектора упоминается неиспользуемый элемент. Предположим, в структуре текущего обрабатываемого HTML-документа нет элементов типа aside
, но есть элементы section
и div
. Тогда, очевидно, CSS-правила
aside {…}
и даже
div section aside {…}
практически не скажутся на производительности обработки CSS-кода. Установить, что текущий обрабатываемый элемент не является элементом типа aside
— дело одного мгновения, каковым вполне можно пренебречь.
А вот временем обработки правила наподобие такого:
section aside div {…}
в общем случае пренебречь уже нельзя, поскольку в рамках классического сценария тут надлежит проверить вложенность каждого встретившегося элемента div
внутрь некоторого элемента aside
.
Другое дело, что во многих браузерах вследствие внутренней оптимизации время обработки подобных селекторов может быть сведено к минимуму. Сказанное может оказаться справедливым по отношению к упоминаемым в CSS-селекторах неиспользуемым типам элементов, классам, идентификаторам, но все же будьте готовы, что правило наподобие
[title*="foo"] * {…}
даже при гарантированном отсутствии элементов с какими угодно значениями атрибута title
в коде разметки будет обрабатываться во всех наличествующих в реальной жизни браузерах едва ли быстрее, чем бесконечно долго…
На этом, пожалуй, закончим подзатянувшуюся теоретическую часть нашей серии статей. В следующий раз попытаемся осмыслить разнообразные тесты производительности обработки селекторов, чтобы представить себе порядок возможной практической экономии ресурсов.
Продолжение следует…
селекторов | Документация по jQuery API
Выберите все элементы, которые находятся в процессе анимации во время запуска селектора.
Выбирает элементы, которые имеют указанный атрибут со значением, равным заданной строке или начинающимся с этой строки, за которой следует дефис (-).
Выбирает элементы, которые имеют указанный атрибут со значением, содержащим данную подстроку.
Выбирает элементы, которые имеют указанный атрибут со значением, содержащим заданное слово, разделенное пробелами.
Выбирает элементы, которые имеют указанный атрибут со значением, оканчивающимся точно на заданную строку. При сравнении учитывается регистр.
Выбирает элементы, которые имеют указанный атрибут со значением, точно равным определенному значению.
Выберите элементы, которые либо не имеют указанного атрибута, либо имеют указанный атрибут, но не имеют определенного значения.
Выбирает элементы, которые имеют указанный атрибут со значением, начинающимся точно с заданной строки.
Выбирает все элементы кнопки и элементы типа кнопка.
Устанавливает флажок для всех элементов типа.
Соответствует всем отмеченным или выбранным элементам.
Выбирает все прямые дочерние элементы, заданные «дочерним» из элементов, заданных «родительским».
Выбирает все элементы данного класса.
Выбрать все элементы, содержащие указанный текст.
Выбирает все элементы, являющиеся потомками данного предка.
Выбирает все отключенные элементы.
Выбирает все элементы с заданным именем тега.
Выберите все элементы, у которых нет дочерних элементов (включая текстовые узлы).
Выбирает все включенные элементы.
Выберите элемент с индексом n в согласованном наборе.
Выбирает четные элементы с нулевым индексом. См. Также: odd.
Выбирает все элементы типа файла.
Выбирает все элементы, которые являются первыми дочерними элементами своего родителя.
Выбирает все элементы, которые являются первыми среди братьев и сестер с тем же именем элемента.
Выбирает первый совпавший элемент DOM.
Выбирает элемент, если он в данный момент сфокусирован.
Выбрать все элементы с индексом больше индекса в согласованном наборе.
Выбирает элементы с указанным атрибутом с любым значением.
Выбирает элементы, содержащие хотя бы один элемент, соответствующий указанному селектору.
Выбирает все элементы, которые являются заголовками, например h2, h3, h4 и т. Д.
Выбирает все скрытые элементы.
Выбирает один элемент с заданным атрибутом id.
Выбирает все элементы типа image.
Выбирает все элементы input, textarea, select и button.
Выбирает все элементы указанного языка.
Выбирает все элементы, которые являются последними дочерними элементами своего родителя.
Выбирает все элементы, которые являются последними среди братьев и сестер с тем же именем элемента.
Выбирает последний совпавший элемент.
Выбрать все элементы с индексом меньше индекса в согласованном наборе.
Соответствует элементам, которые соответствуют всем указанным фильтрам атрибутов.
Выбирает объединенные результаты всех указанных селекторов.
Выбирает все следующие элементы, соответствующие «next», которым непосредственно предшествует элемент «prev».
Выбирает все одноуровневые элементы, следующие после элемента «prev», имеющие одного и того же родителя и соответствующие фильтрующему селектору «братьев и сестер».
Выбирает все элементы, не соответствующие заданному селектору.
Выбирает все элементы, являющиеся n-м потомком своего родителя.
Выбирает все элементы, являющиеся n-м дочерним элементом своего родителя, начиная с последнего элемента до первого.
Выбирает все элементы, которые являются n-м потомком своего родителя по отношению к братьям и сестрам с тем же именем элемента, считая от последнего элемента до первого.
Выбирает все элементы, которые являются n-м потомком своего родителя по отношению к братьям и сестрам с тем же именем элемента.
Выбирает нечетные элементы с нулевым индексом. См. Также: даже.
Выбирает все элементы, которые являются единственными дочерними элементами своего родителя.
Выбирает все элементы, у которых нет братьев и сестер с таким же именем элемента.
Выберите все элементы, у которых есть хотя бы один дочерний узел (элемент или текст).
Выбирает все элементы типа пароля.
Выбирает все элементы типа радио.
Выбирает все элементы типа сброса.
Выбирает элемент, являющийся корнем документа.
Выбирает все выбранные элементы.
Выбирает все элементы типа submit.
Выбирает целевой элемент, указанный идентификатором фрагмента URI документа.
Выбирает все элементы ввода текста.
Выбирает все видимые элементы.
Селектор | Пример | Выбирает |
---|---|---|
* | $ («*») | Все элементы |
# id | $ («# фамилия») | Элемент с |
. класс | $ («. Вступление») | Все элементы с |
. класс, . класс | $ («. Intro, .demo») | Все элементы с классом «intro» или «demo» |
элемент | $ («п») | Все элементы |
el1 , el2 , el3 | $ («h2, div, p») | Все элементы, и |
: первый | $ («p: first») | Первый элемент |
: последние | $ («p: last») | Последний элемент |
: даже | $ («tr: even») | Все четные элементы |
: нечет | $ («tr: odd») | Все нечетные элементы |
: первенец | $ («p: первенец») | Все элементы , которые являются первыми дочерними элементами своих родительских |
: первый в своем роде | $ («р: первоклассный») | Все элементы , которые являются первым элементом своих родительских |
: последний ребенок | $ («p: last-child») | Все элементы , являющиеся последними дочерними элементами своих родительских |
: последний тип | $ («p: последний из числа») | Все элементы , которые являются последним элементом своих родительских |
: nth-ребенок ( n ) | $ («p: nth-child (2)») | Все элементы , которые являются вторыми дочерними элементами своего родителя |
: nth-последний-ребенок ( n ) | $ («p: nth-last-child (2)») | Все элементы , которые являются вторыми дочерними элементами своего родителя, начиная с последний ребенок |
: nth-of-type ( n ) | $ («p: nth-of-type (2)») | Все элементы , которые являются вторым элементом своих родительских |
: nth-last-of-type ( n ) | $ («p: nth-last-of-type (2)») | Все элементы , которые являются вторым элементом своего родителя, считая от последний ребенок |
: только ребенок | $ («p: only-child») | Все элементы , которые являются единственными дочерними элементами их родительского |
: только тип | $ («p: only-of-type») | Все элементы , которые являются единственными дочерними по своему типу, по отношению к их родительскому |
родитель> ребенок | $ («div> p») | Все элементы , которые являются прямым потомком элемента |
родитель-потомок | $ («div p») | Все элементы , являющиеся потомками элемента |
элемент + следующий | $ («div + p») | Элемент , который находится рядом с каждым элементом |
элемент ~ братья и сестры | $ («div ~ p») | Все элементы , которые появляются после элемента |
: eq ( индекс ) | $ («ul li: eq (3)») | Четвертый элемент в списке (индекс начинается с 0) |
: GT ( № ) | $ («ul li: gt (3)») | Элементы списка с индексом больше 3 |
: LT ( № ) | $ («ul li: lt (3)») | Элементы списка с индексом меньше 3 |
: нет ( селектор ) | $ («ввод: не (: пусто)») | Все непустые входные элементы |
: заголовок | $ («: заголовок») | Все элементы заголовка,… |
: анимированные | $ («: animated») | Все анимированные элементы |
: фокус | $ («: focus») | Элемент, который в настоящее время имеет фокус |
: содержит ( текст ) | $ («: содержит (‘Привет’)») | Все элементы, содержащие текст «Hello» |
: имеет ( селектор ) | $ («div: has (p)») | Все элементы , у которых есть элемент |
: пусто | $ («: пусто») | Все пустые элементы |
: родитель | $ («: parent») | Все элементы, являющиеся родительскими для другого элемента |
: скрыто | $ («p: скрыто») | Все скрытые элементы |
: видимый | $ («таблица: видимая») | Все видимые таблицы |
: корень | $ («: root») | Корневой элемент документа |
: язык ( язык ) | $ («p: lang (de)») | Все элементы со значением атрибута lang, начинающимся с «de» |
[ атрибут ] | $ («[href]») | Все элементы с атрибутом href |
[ атрибут = значение ] | $ («[href = ‘по умолчанию. = ‘Том’]») | Все элементы со значением атрибута title, начинающимся с «Tom» |
[ атрибут ~ = значение ] | $ («[title ~ = ‘hello’]») | Все элементы со значением атрибута title, содержащим конкретное слово «hello» |
[ атрибут * = значение ] | $ («[title * = ‘привет’]») | Все элементы со значением атрибута title, содержащим слово «hello» |
: вход | $ («: ввод») | Все элементы ввода |
: текст | $ («: текст») | Все входные элементы с type = «text» |
: пароль | $ («: пароль») | Все элементы ввода с type = «password» |
: радио | $ («: радио») | Все входные элементы с type = «radio» |
: флажок | $ («: флажок») | Все элементы ввода с type = «checkbox» |
: отправить | $ («: отправить») | Все входные элементы с type = «submit» |
: сброс | $ («: сброс») | Все элементы ввода с type = «reset» |
: кнопка | $ («: button») | Все элементы input с type = «button» |
: изображение | $ («: image») | Все входные элементы с type = «image» |
: файл | $ («: файл») | Все входные элементы с type = «file» |
: включено | $ («: включено») | Все разрешенные элементы ввода |
: отключено | $ («: отключено») | Все отключенные элементы ввода |
: выбрано | $ («: selected») | Все выбранные элементы ввода |
: проверено | $ («: проверено») | Все проверенные элементы ввода |
Селекторы атрибутов — CSS: каскадные таблицы стилей
Селектор атрибута CSS сопоставляет элементы на основе наличия или значения данного атрибута.
Заголовок] {
цвет: фиолетовый;
}
a [href = "https://example.org"] {
цвет: зеленый;
}
a [href * = "example"] {
размер шрифта: 2em;
}
a [href $ = ". org"] {
стиль шрифта: курсив;
}
a [class ~ = "logo"] {
отступ: 2 пикселя;
}
-
[ атрибут ]
- Представляет элементы с именем атрибута attr .
-
[ attr = значение ]
- Представляет элементы с именем атрибута attr , значение которого точно равно значению .
-
[ attr ~ = значение ]
- Представляет элементы с именем атрибута attr , значение которого представляет собой список слов, разделенных пробелами, одно из которых точно соответствует значению .
-
[ attr | = значение ]
- Представляет элементы с именем атрибута attr , значение которого может быть точно , значением или может начинаться со значения , сразу за которым следует дефис,
-
(U + 002D).= значение ]- Представляет элементы с именем атрибута attr , значение которого предваряется (предшествует) значением .
[ attr $ = значение ]
- Представляет элементы с именем атрибута attr , значение которого имеет суффикс (за которым следует) , значение .
[ attr * = значение ]
- Представляет элементы с именем атрибута attr , значение которого содержит по крайней мере одно вхождение значения в строку.
[ attr оператор значение i]
- Добавление
i
(илиI
) перед закрывающей скобкой приводит к тому, что значение сравнивается без учета регистра (для символов в диапазоне ASCII).[ attr оператор значение с]
- Добавление
s
(илиS
) перед закрывающей скобкой приводит к тому, что значение сравнивается с учетом регистра (для символов в диапазоне ASCII).= «https»] [href $ = «. org»] { цвет: зеленый; }HTML
Результат
Языки
CSS
div [lang] { font-weight: жирный; } div: not ([lang]) { стиль шрифта: курсив; } div [lang ~ = "en-us"] { цвет синий; } div [lang = "pt"] { цвет: зеленый; } div [lang | = "zh"] { красный цвет; } div [data-lang = "zh-TW"] { цвет: фиолетовый; }
HTML
Привет, мир!Olá Mundo!您好!您好!世界 您好!Результат
Упорядоченные списки HTML
Спецификация HTML требует, чтобы атрибут
типа
сопоставлялся без учета регистра, поскольку он в основном используется в элементетипа
объекта упорядоченный список не работает без модификатора с учетом регистра.CSS
ol [type = "a"] { список-стиль-тип: нижняя альфа; фон: красный; } ol [type = "a" s] { список-стиль-тип: нижняя альфа; фон: салатовый; } ol [type = "A" s] { тип-стиль-список: верхний-альфа; фон: салатовый; }
HTML
- Пример списка
Результат
Таблицы BCD загружаются только в браузер
[атрибут] | CSS-уловки
Есть много способов выбора элементов в CSS.Самый простой выбор осуществляется по имени тега, например,
p {}
. Почти все, что более конкретно, чем селектор тегов, использует атрибуты —class
иID
оба выбирают эти атрибуты в элементах HTML. Ноclass
иID
— не единственные атрибуты, которые могут выбрать разработчики. Мы можем использовать любых атрибутов элемента в качестве селекторов.Выбор атрибута имеет особый синтаксис. Вот пример:
a [href = "https: // css-tricks.com "] { цвет: # E18728; }
Это селектор с точным соответствием , который будет выбирать только ссылки с точным значением атрибута
href
https://css-tricks.com.Семь различных типов
Селекторы атрибутов по умолчанию чувствительны к регистру (см. Сопоставление без учета регистра ниже) и записываются внутри скобок
[]
.Существует семь различных типов совпадений, которые можно найти с помощью селектора атрибутов, и для каждого из них используется свой синтаксис.Каждый из более сложных селекторов атрибутов основан на синтаксисе селектора точного соответствия — все они начинаются с имени атрибута и заканчиваются знаком равенства, за которым следует значение (я) атрибута, обычно в кавычках. То, что находится между именем атрибута и знаком равенства, и есть разница между селекторами.
[значение-данные] { / * Атрибут существует * / } [data-value = "foo"] { / * Атрибут имеет это точное значение * / } [значение-данных * = "foo"] { / * Значение атрибута где-то в нем содержится это значение * / } [значение-данных ~ = "foo"] { / * Атрибут имеет это значение в списке, разделенном пробелами * / } [значение-данных ^ = "foo"] { / * Значение атрибута начинается с этого * / } [значение-данных | = "foo"] { / * Значение атрибута начинается с этого в списке, разделенном тире * / } [data-value $ = "foo"] { / * Значение атрибута заканчивается этим * / }
Значение содержит: значение атрибута содержит термин как единственное значение, значение в списке значений или как часть другого значения.Чтобы использовать этот селектор, добавьте звездочку (*) перед знаком равенства. Например,
img [alt * = "art"]
выберет изображения с альтернативным текстом «abstract art » и «спортсмен , начинающий новый вид спорта», потому что значение «art» находится в слове «start». ».Значение находится в списке, разделенном пробелами: значение является либо единственным значением атрибута, либо целым значением в наборе значений, разделенных пробелами. В отличие от селектора «содержит», этот селектор не будет искать значение как фрагмент слова.= «Искусство»] выберет изображения с альтернативным текстом «арт-шоу» и «художественный узор», но не изображения с альтернативным текстом «Артур Миллер», потому что «Артур» начинается с заглавной буквы.
Значение стоит первым в списке, разделенном тире: Этот селектор очень похож на селектор «начинается с». Здесь селектор соответствует значению, которое является либо единственным значением, либо первым в списке значений, разделенных тире. Чтобы использовать этот селектор, добавьте вертикальную черту (|) перед знаком равенства.Например,
li [data-years | = "1900"]
выберет элементы списка со значениемлет данных
, равным «1900-2000», но не элемент списка со значениемлет данных
, равным « 1800-1900 ».Значение заканчивается на: значение атрибута заканчивается выбранным термином. Чтобы использовать этот селектор, добавьте знак доллара ($) перед знаком равенства. Например,
a [href $ = "pdf"]
выбирает каждую ссылку, которая заканчивается на .pdf.Примечание о кавычках: В некоторых случаях значение можно обходить без кавычек, но правила выбора без кавычек несовместимы в разных браузерах.Цитаты работают всегда, поэтому, если вы будете их использовать, можете быть уверены, что ваш селектор сработает.
См. Селекторы атрибутов пера от CSS-Tricks (@ css-tricks) на CodePen.
Интересный факт: значения обрабатываются как строки, поэтому вам не нужно делать какие-либо причудливые экранирования символов, чтобы они совпадали, как если бы вы использовали необычные символы в селекторе классов или идентификаторов.
[class = "(╯ ° □ °) ╯︵ ┻━┻"] { красный цвет; font-weight: жирный; }
Сопоставление без учета регистра
Селекторы атрибутов без учета регистра являются частью спецификации уровня 4 селекторов рабочей группы CSS.Как упоминалось выше, строки значений атрибутов по умолчанию чувствительны к регистру, но их можно изменить на нечувствительность к регистру, добавив
i
непосредственно перед закрывающей скобкой:[attribute = "value" i] { / * Стили здесь будут применяться к элементам с: attribute = "значение" attribute = "VaLuE" attribute = "VALUE" ...так далее * / }
Сопоставление без учета регистра может быть действительно удобным для нацеливания на атрибуты, содержащие непредсказуемый, написанный человеком текст.Например, предположим, что вы создаете речевой пузырь в приложении чата и хотите добавить «машущую руку» к любым сообщениям с текстом «привет» в той или иной форме. Вы можете сделать это только с помощью CSS, используя сопоставление без учета регистра, чтобы уловить все возможные варианты:
См. Сопоставление атрибутов CSS без учета регистра в ручке с помощью CSS-Tricks (@ css-tricks) на CodePen.
Объединяя их
Вы можете комбинировать селектор атрибутов с другими селекторами, такими как тег, класс или идентификатор.
div [attribute = "value"] { / * здесь правила стиля * / } .модуль [атрибут = "значение"] { / * здесь правила стиля * / } #header [attribute = "value"] { / * здесь правила стиля * / }
Или даже комбинируйте несколько селекторов атрибутов. В этом примере выбираются изображения с замещающим текстом, который включает слово «человек» в качестве единственного значения или значение в списке, разделенном пробелами, и — значение
src
, которое включает значение «lorem»:img [alt ~ = "person"] [src * = "lorem"] { / * здесь правила стиля * / }
См. Раздел «Комбинированные атрибуты пера и выбор только атрибутов» с помощью CSS-Tricks (@ css-tricks) на CodePen.
Селекторы атрибутов в JavaScript и jQuery
Селекторы атрибутов могут использоваться в jQuery, как и любой другой селектор CSS. В JavaScript вы можете использовать селекторы атрибутов с
document.querySelector ()
иdocument.querySelectorAll ()
.См. Селекторы атрибутов пера в JS и jQuery от CSS-Tricks (@ css-tricks) на CodePen.
Связанные
Дополнительная информация
Поддержка браузера
Хром Safari Firefox Opera IE Android iOS Любая Любая любое Любая 7+ Любая Любая Тест селектора атрибутов jQuery — JSFiddle
Редактор макета
Классический Столбцы Нижние результаты Правильные результаты Вкладки (столбцы) Вкладки (строки)
Консоль
Консоль в редакторе (бета)
Очистить консоль при запуске
Общие
Номера строк
Обернуть линии
Отступ с табуляцией
Подсказка по коду (автозаполнение) (бета)
Размер отступа:2 пробела 3 пробела 4 пробела
Ключевая карта:По умолчанию: Sublime TextEMACS
Размер шрифта:По умолчаниюBigBiggerJabba
Поведение
Код автозапуска
Только код автозапуска, который проверяет
Код автосохранения (натыкается на версию)
Автоматически закрывать HTML-теги
Автоматически закрывающие скобки
Проверка действующего кода
Выделите совпадающие теги
Заглушки
Показывать панель шаблонов реже
Селекторы jQuery — javatpoint
Селекторы jQuery используются для выбора и управления элементами HTML.Они очень важная часть библиотеки jQuery.
С помощью селекторов jQuery вы можете находить или выбирать элементы HTML на основе их идентификаторов, классов, атрибутов, типов и многого другого из DOM.
Проще говоря, вы можете сказать, что селекторы используются для выбора одного или нескольких элементов HTML с помощью jQuery, и после выбора элемента вы можете выполнять с ним различные операции.
Все селекторы jQuery начинаются со знака куколки и скобок, например $ (). Это известно как заводская функция.
Каждый селектор jQuery начинается с этого знака $ (). Этот знак известен как заводская функция. Он использует три основных строительных блока при выборе элемента в данном документе.
S. No. Селектор Описание 1) Имя тега: Он представляет имя тега, доступное в DOM.
Например: $ (‘p’) выделяет все абзацы’p’ в документе.2) ID тега: Он представляет тег, доступный с определенным идентификатором в DOM.
Например: $ (‘# real-id’) выбирает в документе определенный элемент, имеющий идентификатор real-id.3) Класс тега: Он представляет тег, доступный с определенным классом в DOM.
Например: $ (‘real-class’) выбирает все элементы в документе, которые имеют класс real-class.Давайте рассмотрим простой пример, чтобы увидеть использование селектора тегов. При этом будут выбраны все элементы с именем тега
, а цвет фона установлен на «розовый».
Это первый абзац.
Это второй абзац.
Это третий абзац.
Селекторы jQuery можно использовать по отдельности или в сочетании с другими селекторами. Они требуются на каждом этапе использования jQuery. Они используются для выбора именно того элемента, который вы хотите из своего HTML-документа.
S. No. Селектор Описание 1) Имя: Он выбирает все элементы, которые соответствуют заданному имени элемента. 2) #ID: Он выбирает единственный элемент, который соответствует заданному идентификатору. 3) .Class: Он выбирает все элементы, которые соответствуют данному классу. 4) Универсальный (*) Выбирает все элементы, доступные в DOM. 5) Несколько элементов A, B, C Он выбирает объединенные результаты всех указанных селекторов A, B и C. Селектор Пример Описание * $ («*») Используется для выбора всех элементов. #id $ («# firstname») Будет выбран элемент с .class $ («. Primary») Он выберет все элементы с class, .class $ («. primary, .secondary») Он выберет все элементы с классом «primary» или «secondary» element $ («p») Будет выберите все элементы p. el1, el2, el3 $ («h2, div, p») Он выберет все элементы h2, div и p. : первый $ («p: first») Будет выбран первый элемент p : последний $ («p: last») Будет выбран последний элемент p : четный $ («tr: четный») При этом будут выбраны все четные элементы tr. : odd $ («tr: odd») Это выберет все нечетные элементы tr. : first-child $ («p: first-child») Он выберет все элементы p, которые являются первыми дочерними элементами своего родителя : first-of-type $ ( «p: first-of-type») Он выберет все элементы p, которые являются первым элементом p своего родителя : last-child $ («p: last-child») It выберет все элементы p, которые являются последними дочерними элементами их родителя. : last-of-type $ («p: last-of-type») Будет выберите все элементы p, которые являются последним элементом p их родительского элемента : nth-child (n) $ («p: nth-child (2)») Это выберет все элементы p, которые являются 2-й дочерний элемент их родителя : nth-last-child (n) $ («p: nth-last-child (2)») При этом будут выбраны все элементы p, которые являются вторыми дочерними элементами их родительский, считая от последнего дочернего элемента : nth-of-type (n) $ («p: nth-of-type (2)») Он выберет все элементы p, которые являются вторыми p элемент их родительского элемента : nth-last-of-type (n) $ («p: nth-last-of-type (2)») Это выберет все элементы p, которые являются вторыми p элемента их родителя, считая от последнего дочернего элемента : only-child $ («p: only-child») Он выберет все элементы p, которые являются единственными дочерними элементами их родителя : только тип $ («p: only-of-type») Он выберет все элементы p, которые являются единственными дочерними элементами своего типа своего родителя parent> child $ («div> p») Он выберет все элементы p, которые являются прямым потомком элемента div родительский потомок $ («div p») Он выберет все элементы p, которые являются потомками элемента div element + next $ («div + p») Он выбирает элемент p, который находится рядом с каждым элементом div element ~ siblings $ («div ~ p») Он выбирает все p элементов, которые являются родственниками элемента div : eq (index) $ («ul li: eq (3)») Будет выбран четвертый элемент в списке (индекс начинается с 0) 901 27: gt (no) $ («ul li: gt (3)») Выберите элементы списка с индексом больше 3 : lt (no) $ («ul li: lt (3)») Выберите элементы списка с индексом меньше 3 : not (селектор) $ («input: not (: empty) «) Выбрать все непустые элементы ввода : header $ («: header «) Выбрать все элементы заголовка h2, h3… : animated $ («: animated») Выбрать все анимированные элементы : focus $ («: focus») Выбрать элемент, который в данный момент находится в фокусе : contains (text) $ («: contains (‘Hello’)») Выбрать все элементы, содержащие текст «Hello» : has (selector) $ («div: has ( p) «) Выбрать все элементы div с элементом ap : empty $ («: empty «) Выбрать все пустые элементы : parent $ («: parent «) Выбрать все элементы, которые являются родительскими для другого элемента : hidden $ (» p: hidden «) Выбрать все скрытые элементы p : visible $ (» table: visible «) Выбрать все видимые таблицы : root $ («: root «) Будет выбран корневой элемент документа : lang (language) $ (» p: lang (de) «) Выбрать все элементы p со значением атрибута lang, начинающимся с» de » [атрибут] $ («[href]») Выбрать все элементы с атрибутом href [атрибут = значение] $ («[href = ‘default. = ‘Tom’]») Выбрать все элементы со значением атрибута заголовка, начинающимся with «Tom» [attribute ~ = value] $ («[title ~ = ‘hello’]») Выбрать все элементы со значением атрибута title, содержащим конкретное слово «hello» 90 137 [атрибут * = значение] $ («[title * = ‘hello’]») Выбрать все элементы со значением атрибута title, содержащим слово «hello» : input $ («: input») Он выберет все элементы ввода : text $ («: text») Он выберет все элементы ввода с type = «text» : password $ («: password») Он выберет все элементы ввода с type = «password» : radio $ («: radio») Он выберет все элементы ввода с type = «radio « : checkbox $ («: checkbox «) Он выберет все элементы ввода с type =» checkbox « : submit $ («: submit «) Он выберет все элементы ввода с type = «submit» : reset $ («: reset») Будет выбран Все элементы ввода с type = «reset» : button $ («: button») Он выберет все элементы ввода с type = «button» : image $ («: image «) Он выберет все элементы ввода с type =» image « : file $ («: file «) Он выберет все элементы ввода с type =» file « : enabled $ («: enabled») Выбрать все включенные элементы ввода : disabled $ («: disabled») Будет выбрано все отключенные элементы ввода : выбрано $ («: selected») Он выберет все выбранные элементы ввода : checked $ («: checked») Он выберет все проверенные элементы ввода
.jQuery Selectors
Селектор Пример Выбирает * $ («*») Все элементы # id $ («# фамилия») Элемент с . класс $ («. Вступление») Все элементы с . класс, . класс $ («. Intro, .demo») Все элементы с классом «intro» или «demo» элемент $ («п») Все элементы el1 , el2 , el3 $ («h2, div, p») Все элементы ,
и: первый $ («p: first») Первый элемент : последние $ («p: last») Последний элемент : даже $ («tr: even») Все четные элементы : нечет $ («tr: odd») Все нечетные элементы : первенец $ («p: первенец») Все элементы , которые являются первыми дочерними элементами своих родительских
: первый в своем роде $ («р: первоклассный») Все элементы , которые являются первым элементом
своих родительских
: последний ребенок $ («p: last-child») Все элементы , являющиеся последними дочерними элементами своих родительских
: последний тип $ («p: последний из числа») Все элементы , которые являются последним элементом
своих родительских
: nth-ребенок ( n ) $ («p: nth-child (2)») Все элементы , которые являются вторыми дочерними элементами своего родителя
: nth-последний-ребенок ( n ) $ («p: nth-last-child (2)») Все элементы , которые являются вторыми дочерними элементами своего родителя, начиная с последний ребенок
: nth-of-type ( n ) $ («p: nth-of-type (2)») Все элементы , которые являются вторым элементом
своих родительских
: nth-last-of-type ( n ) $ («p: nth-last-of-type (2)») Все элементы , которые являются вторым элементом
своего родителя, считая от последний ребенок
: только ребенок $ («p: only-child») Все элементы , которые являются единственными дочерними элементами их родительского
: только тип $ («p: only-of-type») Все элементы , которые являются единственными дочерними по своему типу, по отношению к их родительскому
родитель> ребенок $ («div> p») Все элементы , которые являются прямым потомком элемента
родитель-потомок $ («div p») Все элементы , являющиеся потомками элемента
элемент + следующий $ («div + p») Элемент , который находится рядом с каждым элементом
элемент ~ братья и сестры $ («div ~ p») Все элементы , являющиеся родственниками элемента
: eq ( индекс ) $ («ul li: eq (3)») Четвертый элемент в списке (индекс начинается с 0) : GT ( № ) $ («ul li: gt (3)») Элементы списка с индексом больше 3 : LT ( № ) $ («ul li: lt (3)») Элементы списка с индексом меньше 3 : нет ( селектор ) $ («ввод: не (: пусто)») Все непустые входные элементы : заголовок $ («: заголовок») Все элементы заголовка ,
…
: анимированные $ («: animated») Все анимированные элементы : фокус $ («: focus») Элемент, который в настоящее время имеет фокус : содержит ( текст ) $ («: содержит (‘Привет’)») Все элементы, содержащие текст «Hello» : имеет ( селектор ) $ («div: has (p)») Все элементы , у которых есть элемент: пусто $ («: пусто») Все пустые элементы : родитель $ («: parent») Все элементы, являющиеся родительскими для другого элемента : скрыто $ («p: скрыто») Все скрытые элементы : видимый $ («таблица: видимая») Все видимые таблицы : корень $ («: root») Корневой элемент документа : язык ( язык ) $ («p: lang (de)») Все элементы со значением атрибута lang, начинающимся с «de»
[ атрибут ] $ («[href]») Все элементы с атрибутом href [ атрибут = значение ] $ («[href = ‘по умолчанию. = ‘Том’]») Все элементы со значением атрибута title, начинающимся с «Tom» [ атрибут ~ = значение ] $ («[title ~ = ‘hello’]») Все элементы со значением атрибута title, содержащим конкретное слово «hello» [ атрибут * = значение ] $ («[title * = ‘привет’]») Все элементы со значением атрибута title, содержащим слово «hello» : вход $ («: ввод») Все элементы ввода : текст $ («: текст») Все входные элементы с type = «text» : пароль $ («: пароль») Все элементы ввода с type = «password» : радио $ («: радио») Все входные элементы с type = «radio» : флажок $ («: флажок») Все элементы ввода с type = «checkbox» : отправить $ («: отправить») Все входные элементы с type = «submit» : сброс $ («: сброс») Все элементы ввода с type = «reset» : кнопка $ («: button») Все элементы input с type = «button» : изображение $ («: image») Все входные элементы с type = «image» : файл $ («: файл») Все входные элементы с type = «file» : включено $ («: включено») Все разрешенные элементы ввода : отключено $ («: отключено») Все отключенные элементы ввода : выбрано $ («: selected») Все выбранные элементы ввода : проверено $ («: проверено») Все проверенные элементы ввода