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.