Как найти элемент по data атрибуту js
важность: 5
Напишите код для выбора элемента с атрибутом data-widget-name из документа и прочитайте его значение.
Choose the genre
Choose the genre
.dataset
Простейший способ хранить данные в HTML и читать их из JavaScript.
Время чтения: 5 мин
Открыть/закрыть навигацию по статье
- Кратко
- Как пишется
- Использование camelCase и kebab-case
- Удаление дата-атрибута
- Егор Огарков советует
Обновлено 28 ноября 2022
Кратко
Скопировать ссылку «Кратко» Скопировано
Свойство dataset позволяет считывать или устанавливать любые дата-атрибуты на HTML-элементе.
Дата-атрибут — это пользовательский атрибут на элементе, название которого начинается с data — , например data — testid . Дата атрибуты используются, чтобы хранить значения на элементах в HTML.
Как пишется
Скопировать ссылку «Как пишется» Скопировано
Обращение к свойству dataset вернёт объект со всеми дата-атрибутами, которые есть на элементе. Названиями полей в объекте будут имена дата-атрибутов после префикса data — . Например, если атрибут называется data — columns , то поле в объекте для этого атрибута будет называться columns .
const items = document.querySelectorAll('li') const firstItem = items[0] console.log(firstItem.dataset)//const items = document.querySelectorAll('li') const firstItem = items[0] console.log(firstItem.dataset) //Если дата-атрибутов на элементе нет, то вернётся пустой объект:
const heading = document.querySelector('h1') console.log(heading.dataset)// <>const heading = document.querySelector('h1') console.log(heading.dataset) // <>Чтобы добавить дата-атрибут к элементу, нужно добавить новое поле в объект dataset . Название поля так же должно быть без префикса data — , браузер автоматически подставит его. В значениях атрибутов в HTML могут быть только строки, потому любое значение будет автоматически приведено к строке.
Возьмём тот же HTML из примера выше и добавим дата-атрибуты ко второму элементу:
const items = document.querySelectorAll('li') const secondItem = items[1] secondItem.dataset.side = 'evil'secondItem.dataset.age = 46secondItem.dataset.lightsaber =const items = document.querySelectorAll('li') const secondItem = items[1] secondItem.dataset.side = 'evil' secondItem.dataset.age = 46 secondItem.dataset.lightsaber = color: 'red' >В результате получим такой элемент:
data-id="9434" data-episode="4" data-side="evil" data-age="46" data-lightsaber="[object Object]"> Дарт Вейдерli data-id="9434" data-episode="4" data-side="evil" data-age="46" data-lightsaber="[object Object]"> Дарт Вейдер li>Все не строковые значения установленные в dataset будут приводиться к строке. Поэтому объект превращается в [object Object ] , а число 46 превращается в строку «46» .
Если в dataset добавить поле с пустым значением, то в HTML будет создан дата-атрибут без значения.
Использование camelCase и kebab-case
Скопировать ссылку «Использование camelCase и kebab-case» Скопировано
В dataset необходимо присваивать поля, название которых записывается в одно слово. Потому для составных имён используется только camel Case нотация. При попытке присвоить название в kebab — case будет выброшена ошибка.
const body = document.querySelector('body') body.dataset['dark-theme'] = true // Uncaught DOMException: Failed to set// a named property on 'DOMStringMap':// 'dark-theme' is not a valid property name.const body = document.querySelector('body') body.dataset['dark-theme'] = true // Uncaught DOMException: Failed to set // a named property on 'DOMStringMap': // 'dark-theme' is not a valid property name.Дата-атрибуты, записанные в dataset с помощью camel Case , в HTML будут иметь названия в kebab — case . Браузер преобразует camel Case в kebab — case :
const item = document.querySelector('li') item.dataset.yearsOfExperience = 2item.dataset.candidateRole = 'junior'const item = document.querySelector('li') item.dataset.yearsOfExperience = 2 item.dataset.candidateRole = 'junior'После выполнения кода выше получится следующий HTML:
Преобразование названий работает и в обратную сторону – дата-атрибут на HTML-элементе, записанный в kebab — case , будет превращён в dataset в camel Case .
const item = document.querySelector('li') console.log(item.dataset)//const item = document.querySelector('li') console.log(item.dataset) //Удаление дата-атрибута
Скопировать ссылку «Удаление дата-атрибута» Скопировано
Удалить дата-атрибут можно только с помощью оператора delete . Если попытаться присвоить к полю значение undefined или null , то браузер просто присвоит атрибуту строку ‘undefined’ или ‘null’ .
Возьмём следующий HTML:
Любое содержимоеdiv data-testid="test">Любое содержимоеdiv>При установке undefined в значение дата-атрибута, он не удалится с элемента.
const element = document.querySelector('div') element.dataset.testid = undefinedconst element = document.querySelector('div') element.dataset.testid = undefinedВ результате получится следующий HTML:
Любое содержимоеdiv data-testid="undefined">Любое содержимоеdiv>Если использовать оператор delete , то получим элемент без дата-атрибута.
delete element.dataset.testiddelete element.dataset.testidЛюбое содержимоеdiv>Любое содержимоеdiv>Свойство dataset защищено от перезаписи. Это значит что попытка присвоить в dataset новое значение будет проигнорирована.
const element = document.querySelector('div') // Ничего не произойдёт, дата-атрибуты на элементах тоже не изменятсяelement.dataset = <>element.dataset = 'string'const element = document.querySelector('div') // Ничего не произойдёт, дата-атрибуты на элементах тоже не изменятся element.dataset = > element.dataset = 'string'Как понять
Скопировать ссылку «Как понять» Скопировано
Дата-атрибуты появились в HTML5 и добавили возможность разработчикам добавлять свои собственные атрибуты к элементам. Причин для использования таких атрибутов можно придумать множество, чаще всего в дата-атрибутах хранят нужные значения, которые используют в CSS или JavaScript.
Дата-атрибуты были созданы специально для того, чтобы хранить и работать с данными прямо в HTML. Отсюда и префикс data, что в переводе значит данные. Например, с помощью дата-атрибутов можно хранить значение выбранное в селекте прямо на элементе.
Хранение данных на HTML-элементах так же полезно для инициализации виджетов в JavaScript. Они могут находить нужные элементы используя дата-атрибут как селектор, и читать данные из атрибута. Например, в многостраничных приложениях HTML генерируется на сервере и готовая страница отправляется в ответ на запрос. Во время генерации в HTML можно подставить дата-атрибуты с данными с сервера, и таким образом пробросить их в JavaScript.
В теории для такой же цели можно использовать и обычный идентификатор id , но цель у этого атрибута совсем другая. Плюс спецификация требует чтобы значение атрибута id было уникальным на всем странице.
Дата-атрибутов на элементе может быть сколько угодно, потому удобно располагать отдельные кусочки данных в свой атрибут. Такого точно нельзя достичь, используя только идентификатор.
Браузер даёт возможность управлять дата-атрибутами через специальное API dataset .
На практике
Скопировать ссылку «На практике» Скопировано
Егор Огарков советует
Скопировать ссылку «Егор Огарков советует» Скопировано
Дата-атрибут можно использовать для применения стилей. Элементы можно выделять CSS-селектора по атрибуту:
[data-id] /* Селектор для всех элементов с data-id */> [data-id="123"] /* Селектор только для элементов с data-id="123" */>[data-id] /* Селектор для всех элементов с data-id */ > [data-id="123"] /* Селектор только для элементов с data-id="123" */ >Найти элемент с data — id = «123» :
const element = document.querySelector('[data-id="123"]')const element = document.querySelector('[data-id="123"]')Некоторые фреймворки во время компиляции самостоятельно генерируют дата-атрибуты и присваивают их к элементам, чтобы делать изоляцию CSS.
Дата-атрибуты широко используются в автоматизированном тестировании. Для этого на необходимых элементах расставляют дата-атрибуты и тест обращается к ним. В документациях к различным библиотекам для тестирования часто можно встретить атрибут data — testid .
Использование data-* атрибутов
HTML5 (en-US) спроектирован с возможностью расширения данных ассоциированных с каким-либо элементом, но в то же время не обязательно имеющих определённое значение. data-* атрибуты позволяют хранить дополнительную информацию в стандартных элементах HTML, без хаков вроде нестандартных атрибутов, лишних DOM-свойств или Node.setUserData() .
Синтаксис HTML
Синтаксис прост — любой атрибут, чьё имя начинается с data- , является data-* атрибутом. Предположим у нас имеется статья и мы хотим сохранить дополнительную информацию без визуального представления. Для этого можно использовать data -атрибуты:
article id="electriccars" data-columns="3" data-index-number="12314" data-parent="cars"> . article>
Доступ в JavaScript
Чтение data- атрибутов в JavaScript осуществляется также просто. Для этого можно использовать метод getAttribute() с параметром, равным полному имени атрибута. Но есть и более простой способ, используя объект dataset (en-US).
Чтобы получить data -атрибут можно взять свойство объекта dataset с именем, равным части имени атрибута после data- (обратите внимание, что дефисы в имени преобразуются в camelCase).
var article = document.getElementById('electriccars'); article.dataset.columns // "3" article.dataset.indexNumber // "12314" article.dataset.parent // "cars"Каждое свойство является строкой и может быть прочитано и записано. В приведённом выше примере выполнение кода article.dataset.columns = 5 приведёт к тому, что новое значение атрибута станет равным «5» .
Доступ в CSS
Заметим, что data -атрибуты являются обычными HTML-атрибутами, к которым можно получить доступ в CSS. Например, чтобы показать родительские данные о статье можно использовать генерируемый контент и CSS функцию attr() :
article::before content: attr(data-parent); >Также можно использовать селекторы атрибутов в CSS для изменения стилей в соответствии с данным:
article[data-columns="3"] width: 400px; > article[data-columns="4"] width: 600px; >Увидеть как это работает можно в примере на JSBin.
Data -атрибуты также могут использоваться для хранения информации, которая постоянно изменяется, например, счёт в игре. Используя CSS селекторы и возможности JavaScript можно создавать некоторые изящные эффекты, без необходимости писать свои функции отображения. Посмотрите скринкаст чтобы увидеть больше примеров использующих сгенерированный контент и переходы на CSS. Пример кода из скринкаста можно также посмотреть на JSBin.
Проблемы
Не храните данные, которые должны быть видимы и доступны в data -атрибутах. Дело в том, что вспомогательная техника (assistive technology) может не получить к ним доступ. В дополнение, поисковые роботы не индексируют данные, содержащиеся в data -атрибутах.
Печально, что всё простое и полезное в этой жизни не достаётся бесплатно. Internet Explorer 11+ поддерживает этот стандарт, но все более ранние версии не поддерживают dataset . Для поддержки IE 10 и более ранних версий получение доступа к data -атрибутам необходимо осуществлять через getAttribute() . Также, производительность чтения data- атрибутов по сравнению с хранением этих данных в хранилище данных JS значительно хуже. Использование dataset ещё медленнее, чем чтение данных с getAttribute() .
Тем не менее, для пользовательских метаданных, связанных с элементами, data- атрибуты являются отличным решением.
Смотрите также
- This article is adapted from Using data attributes in JavaScript and CSS on hacks.mozilla.org.
- How to use HTML5 data attributes (Sitepoint)
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 3 авг. 2023 г. by MDN contributors.
Как выбрать элемент по data атрибуту на js?
Как выбрать элемент по data атрибуту на чистом js.
На jquery через $(); выбирает, но на js через querySelector не работает. Пишет:
Failed to execute ‘querySelector’ on ‘Document’: ‘.dropdown__content[data-content=6]’ is not a valid selector.var data_id = this.getAttribute('data-id'); var dropdown_content_ths = document.querySelector('.dropdown__content[data-content='+data_id+']');- Вопрос задан более трёх лет назад
- 22856 просмотров
2 комментария
Простой 2 комментария