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

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

Поиск в DOM — первый шаг почти любого браузерного модуля: скрипт получает ссылку на узел и дальше читает данные или вешает обработчики. Современный код опирается на CSS-селекторы через querySelector и querySelectorAll; getElementById остаётся самым быстрым способом для уникальных якорей.


getElementById #

Ищет элемент по значению атрибута id. ID должен быть уникален в документе:

const checkoutForm = document.getElementById('checkout-form')
const playlistRoot = document.getElementById('playlist-root')

Эквивалент через селектор (кавычки в ID экранируйте при необходимости):

document.querySelector('#checkout-form')

Для стабильных точек входа JSFlow (#app, #modal-host) getElementById читается явно и предсказуемо.


querySelector #

Возвращает первый элемент, подходящий под CSS-селектор, или null:

const primaryCta = document.querySelector('.checkout-bar .btn-primary')
const emptyState = document.querySelector('[data-state="empty"]')
const firstTrack = document.querySelector('.playlist .track-row')

Селектор можно уточнять контекстом — искать только внутри контейнера:

const dashboard = document.querySelector('.dashboard')
const kpiWidget = dashboard.querySelector('[data-widget="kpi"]')
const sparkline = kpiWidget.querySelector('canvas')

Так локализуется область поиска и снижается риск зацепить чужой блок на странице.


querySelectorAll #

Возвращает статический NodeList всех совпадений:

const trackRows = document.querySelectorAll('.playlist .track-row')
const metricCards = document.querySelectorAll('[data-metric]')

trackRows.length // число строк
trackRows.forEach((row) => {
  row.classList.remove('is-highlighted')
})

NodeList не массив, но поддерживает forEach. Для map / filter сначала скопируйте:

const ids = [...trackRows].map((row) => row.dataset.trackId)

Сравнение методов #

МетодРезультатСелекторЖивая коллекция
getElementById(id)один элементтолько ID—
querySelector(sel)один элементCSS—
querySelectorAll(sel)NodeListCSSнет
getElementsByClassNameHTMLCollectionклассда
getElementsByTagNameHTMLCollectionтегда

Для нового кода предпочитайте querySelector*: один синтаксис с CSS и поддержка [data-*], :not(), комбинаторов.


Практика: дашборд и checkout #

Разметка строки заказа:

<li class="cart-line" data-sku="kb-01">
  <span class="cart-line__name">Клавиатура</span>
  <span class="cart-line__qty">2</span>
</li>

Обновить количество по SKU:

function setLineQty(sku, qty) {
  const line = document.querySelector(`.cart-line[data-sku="${sku}"]`)
  if (!line) return

  const qtyEl = line.querySelector('.cart-line__qty')
  qtyEl.textContent = String(qty)
}

setLineQty('kb-01', 3)

Подсветить все виджеты с предупреждением:

document.querySelectorAll('.widget[data-severity="warn"]').forEach((widget) => {
  widget.classList.add('widget--pulse')
})

Ошибки и null #

querySelector не бросает исключение, если ничего не найдено — проверяйте результат:

const submitBtn = document.querySelector('#checkout-form [type="submit"]')

if (!submitBtn) {
  throw new Error('кнопка отправки checkout не найдена')
}

submitBtn.disabled = false

Избегайте «склеивания» селекторов из пользовательского ввода без экранирования — риск некорректного селектора или неожиданных совпадений.


Итог #

  • getElementById — для уникальных якорей с id.
  • querySelector — один элемент по CSS-селектору; ищите внутри контейнера для изоляции.
  • querySelectorAll — все совпадения; результат статический.
  • Всегда обрабатывайте null, если элемент может отсутствовать в разметке.

См. также #

Часто спрашивают

querySelector или getElementById?
getElementById быстрее и проще для одного id; querySelector гибче за счёт CSS-селекторов. Подробнее