DOM — селекторы и манипуляции
Document Object Model: поиск элементов, создание, вставка, изменение. Фундамент UI в браузере.
Что это
document — корень DOM-дерева страницы. Все методы поиска и создания узлов сидят на нём. Знать DOM нужно даже если работаешь с React/Vue/Angular — под фреймворком всё равно лежит DOM, и иногда приходится спускаться к нему (refs, custom directives, third-party libs).
Поиск элементов
// По ID — самый быстрый, возвращает Element | null
const header = document.getElementById('header');
// По селектору — мощнее jQuery
const first = document.querySelector('div.header > nav .menu a');
const all = document.querySelectorAll('.card[data-active]'); // NodeList
// По имени тега/класса — живые HTMLCollection (обновляются при изменениях DOM!)
const divs = document.getElementsByTagName('div');
const cards = document.getElementsByClassName('card');
// Удобные алиасы
window.$ = document.querySelector.bind(document);
window.$$ = (sel) => [...document.querySelectorAll(sel)];
Создание и вставка
// Создать элемент
const el = document.createElement('div');
el.className = 'card';
el.textContent = 'Hello'; // безопасно от XSS
el.innerHTML = '<b>HTML</b>'; // только если доверяешь источнику
// Атрибуты
el.setAttribute('data-id', '42');
el.dataset.userId = '42'; // → data-user-id
// Стили
el.style.backgroundColor = 'coral';
el.classList.add('active');
el.classList.toggle('hidden');
// Вставка (современный API)
parent.append(el); // в конец
parent.prepend(el); // в начало
sibling.before(el); // перед
sibling.after(el); // после
sibling.replaceWith(el); // заменить
// Старый API
parent.appendChild(el);
parent.insertBefore(el, before);
// Удаление
el.remove();
// Создание поддерева
const div = Object.assign(document.createElement('div'), {
className: 'card',
innerHTML: '<h2>Title</h2><p>Body</p>',
});
NodeList vs HTMLCollection
| NodeList | HTMLCollection | |
|---|---|---|
| Возвращается из | querySelectorAll |
getElementsBy* |
| Живая? | Чаще нет (статичная) | Да (обновляется!) |
| forEach | Есть | Нет |
| Конвертация | [...nodes] |
[...coll] |
Подводные камни
getElementsByClassNameвозвращает живую коллекцию —coll[i]может стать другим после изменений DOM. Внутри цикла особенно опасноinnerHTML— XSS-риск для user input. ИспользуйtextContentили sanitizequerySelectorтяжелееgetElementById(~10x), для горячих путей лучше первый- Изменение DOM в цикле триггерит layout thrashing — батчи через
DocumentFragmentилиrequestAnimationFrame el.styleчитает только inline-стили, не computed — для computedgetComputedStyle(el)
Используется в bootcamp
- Везде — практически любое DOM-приложение начинается с
document.querySelector - Особо: AsyncRace — создание машинок, Podcast Player — рендер списка эпизодов
Ссылки
🎓 Источники
- 🎓 JavaScript в браузере: Web API (часть 1) · TimurShemsedinov · 2019-10-10
- DOM — основа UI, под любым фреймворком всё равно DOM.
getElementsByClassNameвозвращает живую коллекцию,querySelector— статичный NodeList.querySelectorмощнее, чем jQuery-селекторы — принимает любой CSS-путь.