Урок 02

Поиск элементов

querySelector

Возвращает первый элемент по CSS-селектору:

const el = document.querySelector('.card');
const el2 = document.querySelector('#header');
const el3 = document.querySelector('ul > li:first-child');

Если не нашёл — null.

querySelectorAll

Возвращает все подходящие элементы как NodeList (статический):

const items = document.querySelectorAll('.item');
items.length;
items.forEach((el) => console.log(el));

getElementById

По ID:

const el = document.getElementById('header');

Быстрее querySelector для ID.

getElementsByClassName

Живая коллекция:

const items = document.getElementsByClassName('item');
items.length; // обновляется при изменении DOM

Нужно преобразовать в массив:

const arr = Array.from(items);
const arr2 = [...items];

getElementsByTagName

const divs = document.getElementsByTagName('div');

Живая коллекция.

Поиск внутри элемента

const container = document.querySelector('.container');
const items = container.querySelectorAll('.item');

Ищет только внутри container.

CSS-селекторы

// по классу
document.querySelector('.card');

// по атрибуту
document.querySelector('[data-id="42"]');
document.querySelector('[type="checkbox"]:checked');

// комбинированные
document.querySelector('div.card.active');
document.querySelector('ul > li:first-child');
document.querySelector('a[href^="https"]');
document.querySelector('input:not([disabled])');

// соседние
document.querySelector('h2 + p');
document.querySelector('h2 ~ p');

Псевдоклассы

document.querySelectorAll('li:nth-child(2n)'); // чётные
document.querySelector('input:focus');
document.querySelector('button:disabled');

Псевдоэлементы

querySelector не работает с ::before, ::after — их нельзя получить как элементы.

NodeList vs HTMLCollection

// NodeList — статический
const nl = document.querySelectorAll('div');

// HTMLCollection — живой
const hc = document.getElementsByTagName('div');

NodeList от querySelectorAll поддерживает forEach:

document.querySelectorAll('div').forEach((el) => {});

HTMLCollection — нет:

// Ошибка
const divs = document.getElementsByTagName('div');
divs.forEach(...); // TypeError

// Через Array
[...divs].forEach(...);
Array.from(divs).forEach(...);

Проверка результата

const el = document.querySelector('.missing');

if (el) {
    el.style.color = 'red';
}

querySelector может вернуть null, querySelectorAll — пустую коллекцию.

Оптимизация

Не вызывай querySelector в цикле — кешируй:

// Плохо
for (let i = 0; i < 100; i++) {
    document.querySelector('.container').appendChild(el);
}

// Хорошо
const container = document.querySelector('.container');
for (let i = 0; i < 100; i++) {
    container.appendChild(el);
}

Практика

// Все ссылки на странице
const links = document.querySelectorAll('a[href]');

// Активные чекбоксы
const checked = document.querySelectorAll('input[type="checkbox"]:checked');

// Первый параграф в статье
const firstP = document.querySelector('article p');

// Следующий элемент после заголовка
const next = document.querySelector('h1 + p');

Итоги

  • querySelector — первый элемент или null
  • querySelectorAll — все, статическая коллекция
  • getElementById — быстрее для ID
  • getElementsBy* — живые коллекции
  • Поддерживаются все CSS-селекторы
  • Кешируй результаты поиска