dataset: работа с data-* без getAttribute() и setAttribute()!… — Code Ready | Frontend — TG.ME

dataset: работа с data-* без getAttribute() и setAttribute()!

HTML-атрибуты data-* позволяют хранить данные, непосредственно связанные с конкретным DOM-элементом. Для доступа к таким значениям DOM предоставляет стандартный API dataset.
<button
data-user-id="42"
data-action="delete"
>
Удалить
</button>


Свойство dataset возвращает объект DOMStringMap, через который можно читать значения data-* как свойства JavaScript-объекта.
const button = document.querySelector('button');

console.log(button.dataset.userId);
// "42"

console.log(button.dataset.action);
// "delete"


При формировании имени свойства префикс data- удаляется, а дефис перед строчной ASCII-буквой a-z удаляется, при этом следующая буква преобразуется в верхний регистр. Поэтому data-user-role становится dataset.userRole.
<div
id="user"
data-user-role="admin"
></div>


Это преобразование выполняется самим DOM API, поэтому обращаться к исходному имени атрибута вручную не требуется.
const user = document.querySelector('#user');

console.log(user.dataset.userRole);
// "admin"


dataset поддерживает не только чтение. Присваивание свойства изменяет соответствующий data-* атрибут элемента.
button.dataset.action = 'restore';

console.log(button.getAttribute('data-action'));
// "restore"


Если соответствующего data-* атрибута ещё нет, присваивание через dataset создаст его в DOM.
button.dataset.loading = 'true';

console.log(button.hasAttribute('data-loading'));
// true


Удаление свойства через оператор delete удаляет и соответствующий атрибут элемента.
delete button.dataset.loading;

console.log(button.hasAttribute('data-loading'));
// false


Важная особенность dataset: значения представлены строками. При присваивании числа, boolean и другие значения преобразуются в строковое представление.
button.dataset.userId = 42;
button.dataset.active = true;

console.log(button.dataset.userId);
// "42"

console.log(button.dataset.active);
// "true"

console.log(typeof button.dataset.userId);
// "string"


Если приложению нужен другой тип, преобразование следует выполнять явно. Это особенно важно для чисел и boolean-значений, поскольку строка "false" в JavaScript сама по себе является truthy.
const userId = Number(button.dataset.userId);
const isActive = button.dataset.active === 'true';


Один из практических сценариев для data-* — делегирование событий. При этом использовать event.target.dataset напрямую не всегда корректно: фактической целью события может оказаться вложенный span, svg или другой дочерний элемент.
<ul id="users">
<li>
<button data-user-id="42">
<span>Удалить</span>
</button>
</li>
</ul>


Для такого случая надёжнее найти ближайший подходящий элемент через closest() и дополнительно проверить, что он относится к нужному контейнеру.
const list = document.querySelector('#users');

list.addEventListener('click', event => {
const button =
event.target.closest('[data-user-id]');

if (!button || !list.contains(button)) {
return;
}

const userId =
Number(button.dataset.userId);

removeUser(userId);
});


dataset хорошо подходит для небольших объёмов метаданных, принадлежащих конкретному DOM-элементу: идентификаторов, режимов, состояний интерфейса и параметров поведения.

Для сложных объектов и полноценного состояния приложения data-* использовать не стоит — DOM в таком случае фактически превращается в хранилище состояния, для которого существуют более подходящие структуры данных.
button.dataset.userId = '42';
button.dataset.action = 'delete';
button.dataset.confirm = 'true';


🔥 dataset — стандартный DOM API поверх data-*, который делает работу с пользовательскими атрибутами короче и удобнее, но не обеспечивает типизацию их значений: значения dataset представлены строками и при необходимости требуют явного преобразования.

📣 Code Ready | #практика
👍7❤6🔥5
September 3, 2026 438 14