DOM атрибуты и свойства

Атрибуты — это то, что написано в HTML-разметке; свойства — это живые данные DOM-объекта в JavaScript; они связаны, но не всегда совпадают.

Зачем нужно

Понимание разницы между атрибутами и свойствами критично для корректной работы с формами, состоянием элементов и динамической разметкой. Например, input.value отражает текущее значение поля, а input.getAttribute('value') — только начальное из HTML. Путаница между ними — источник трудноуловимых багов.

Где используется

  • Чтение и запись значений полей форм (input.value, checkbox.checked)
  • Управление классами и data-атрибутами (dataset)
  • Динамическое изменение href, src, disabled и других атрибутов
  • Работа с ARIA-атрибутами (setAttribute('aria-expanded', 'true'))
  • Передача пользовательских данных через data-* атрибуты

Основной контент

Атрибуты через методы DOM

const btn = document.querySelector('button');

// Чтение атрибута
btn.getAttribute('disabled');      // null или ''
btn.getAttribute('data-id');       // строка из HTML

// Запись атрибута
btn.setAttribute('aria-label', 'Закрыть');
btn.setAttribute('disabled', '');

// Удаление атрибута
btn.removeAttribute('disabled');

// Проверка наличия
btn.hasAttribute('disabled');      // true / false

Свойства как JavaScript-значения

const input = document.querySelector('input[type="checkbox"]');

input.checked;          // true / false (текущее состояние)
input.disabled = true;  // установить программно
input.id;               // строка
input.className;        // строка со всеми классами
input.classList;        // DOMTokenList (удобнее)

Разница: атрибут vs свойство

<input type="text" value="начальное">
const input = document.querySelector('input');

input.getAttribute('value'); // 'начальное' — всегда из HTML
input.value;                 // текущий текст в поле (изменяется при вводе)

// После того как пользователь напечатал 'новое':
input.getAttribute('value'); // 'начальное'
input.value;                 // 'новое'

data-* атрибуты и dataset

<article data-id="42" data-author-name="Иван">...</article>
const article = document.querySelector('article');

article.dataset.id;           // '42'
article.dataset.authorName;   // 'Иван' (camelCase)
article.dataset.newProp = 'x'; // создаёт data-new-prop="x"

Булевы атрибуты

Атрибуты disabled, required, checked, readonly считаются установленными при наличии, независимо от значения.

// Правильно
btn.disabled = true;
btn.removeAttribute('disabled');

// Через setAttribute тоже работает
btn.setAttribute('disabled', '');  // присутствие = true
btn.removeAttribute('disabled');   // отсутствие = false

classList для управления классами

el.classList.add('active');
el.classList.remove('active');
el.classList.toggle('open');          // добавить/убрать
el.classList.contains('visible');     // true / false
el.classList.replace('old', 'new');

Частые ошибки

  • Смешивают value атрибут и свойствоsetAttribute('value', x) не меняет видимое содержимое поля, если пользователь уже его редактировал. Используйте input.value = x.
  • Забывают, что getAttribute всегда возвращает строкуel.getAttribute('tabindex') даёт '0', не число. Нужно parseInt или +.
  • Используют className = вместо classList — прямое присвоение el.className = 'foo' затирает все существующие классы.
  • Ожидают, что setAttribute('checked', false) снимет флажок — булевы атрибуты определяются присутствием, не значением. Используйте removeAttribute или свойство checked = false.

Связанные темы

Ресурсы