data-атрибуты (dataset)
data-*— HTML-атрибуты для хранения произвольных пользовательских данных прямо в элементе; доступны из JavaScript через свойствоelement.dataset.
Зачем нужно
data-атрибуты позволяют связать данные с DOM-элементом декларативно, прямо в разметке, без внешних структур данных. Это удобно для делегирования событий, хранения идентификаторов, конфигурации компонентов и передачи данных из шаблонизатора в JavaScript.
Где используется
- Хранение ID сущности (товара, пользователя) прямо в элементе
- Конфигурация UI-компонентов через HTML (tooltips, слайдеры, модалки)
- Передача данных при делегировании событий
- Хранение состояния элемента (выбран, раскрыт, загружается)
Синтаксис
HTML использует kebab-case: data-user-id, JavaScript читает через camelCase: dataset.userId.
<button
data-user-id="42"
data-user-name="Иван"
data-role="admin"
>
Удалить
</button>
const btn = document.querySelector('button');
// Чтение
console.log(btn.dataset.userId); // "42" (всегда строка!)
console.log(btn.dataset.userName); // "Иван"
console.log(btn.dataset.role); // "admin"
// Запись
btn.dataset.status = 'active';
// В HTML появится data-status="active"
// Удаление
delete btn.dataset.role;
Практические примеры
Делегирование событий с данными
const list = document.querySelector('.product-list');
list.addEventListener('click', (event) => {
const btn = event.target.closest('[data-action]');
if (!btn) return;
const { action, productId } = btn.dataset;
if (action === 'add-to-cart') {
addToCart(productId);
} else if (action === 'delete') {
deleteProduct(productId);
}
});
<li>
Товар A
<button data-action="add-to-cart" data-product-id="101">В корзину</button>
<button data-action="delete" data-product-id="101">Удалить</button>
</li>
Конфигурация компонента
document.querySelectorAll('[data-tooltip]').forEach(el => {
el.addEventListener('mouseenter', () => {
showTooltip(el, el.dataset.tooltip, el.dataset.tooltipPosition || 'top');
});
});
Состояние элемента
const accordion = document.querySelector('.accordion');
accordion.addEventListener('click', (event) => {
const header = event.target.closest('.accordion__header');
if (!header) return;
const isOpen = header.dataset.open() === 'true';
header.dataset.open() = String(!isOpen);
header.nextElementSibling.hidden = isOpen;
});
Частые ошибки
- Забыть, что dataset возвращает строки — числа нужно явно преобразовывать:
Number(el.dataset.count)илиparseInt(el.dataset.count, 10). - Хранить большие или сложные данные — dataset не предназначен для объектов; для сложных данных лучше использовать
Mapили WeakMap с элементом в качестве ключа. - Имена с заглавных букв в HTML —
data-UserNameневалидно; все буквы в HTML-атрибуте строчные.
Связанные темы
- _MOC DOM
- _MOC JavaScript
- Атрибуты -- getAttribute, setAttribute
- classList -- add, remove, toggle, contains
- closest -- поиск родителя