Загрузка...

Выбор элементов

На полке пекарни один заголовок и три листка. Заголовок говорит Rye. Листки называют смену: Morning, Noon и Evening. На последнем листке есть ещё класс sold. Полка — это main с id shelf. Внутри h2 с id loaf, затем три элемента p с классом tag. Выбрать — значит попросить живой документ об этих узлах по имени, которое задаёшь ты. document.getElementById("loaf") возвращает заголовок, и его текст — Rye. document.getElementsByClassName("tag") возвращает живой список длины 3. document.querySelector(".tag") возвращает Morning, первый листок. document.querySelectorAll(".tag") возвращает неподвижный список, и индекс 1 — это Noon. Имя, которого на полке нет, приходит как null из querySelector и как список длины 0 из querySelectorAll.

Пять вызовов, не спуск по дереву

Страница DOM называла родителя заголовка и считала дочерние элементы против всех узлов. Здесь не читают parentElement, nextElementSibling и children, и не вызывают Math. Дерево уже есть. На этой странице видно, какой вызов даёт один узел, какой даёт список, и какой ответ значит, что ничего не совпало.

Что возвращает каждый вызов

Считай на полке, где только заголовок и три листка. Файл с итоговой строкой ниже добавляет ещё один абзац, поэтому число элементов p там другое.

📊 Что возвращает каждый вызов

Вызов Что приходит На этой полке Легко перепутать
getElementById("loaf") один элемент или null текст заголовка Rye список, который надо индексировать
getElementsByClassName("tag") живая HTMLCollection длина 3 точка, как в .tag
getElementsByTagName("p") живая HTMLCollection длина 3 сам заголовок, это h2
querySelector(".tag") первое совпадение или null листок Morning все листки
querySelectorAll(".tag") статическая NodeList длина 3; индекс 1 — Noon живая коллекция
querySelectorAll(".oven") пустая NodeList длина 0 null

Метод класса и селектор CSS пишут точку по-разному. getElementsByClassName("tag") ждёт голое имя tag. getElementsByClassName(".tag") ищет класс, который буквально называется .tag, и возвращает длину 0. querySelector ждёт CSS, поэтому точка остаётся у .tag. querySelector("tag") ищет элемент, чьё имя тега — tag, ничего не находит и возвращает null. Индекс 0 — первый листок. Индекс 1 — Noon. Список из getElementsByClassName живой: если поздняя страница добавит ещё один листок tag, длина вырастет. querySelectorAll хранит длину момента вызова. У Evening два класса, tag и sold, поэтому он входит в список длины 3 и он же единственное совпадение для sold.

Один id, один элемент

Id на странице должен быть единственным. getElementById возвращает этот один элемент или null, если id нет. Списка он не возвращает и есть только у document, не у элемента.

Один id

javascript
let loaf = document.getElementById("loaf");
console.log(loaf.textContent);
console.log(loaf === null);

Первая строка — Rye. Вторая — false, потому что заголовок на полке есть. Если два элемента делят id loaf, вызов всё равно вернёт только первый в документе.

Имя класса и имя тега

Оба вызова возвращают живую HTMLCollection. Сначала прочитай length, потом бери один листок. Счёт — на полке из четырёх элементов, не в файле со строкой.

Класс и тег

javascript
console.log(document.getElementsByClassName("tag").length);
console.log(document.getElementsByTagName("p").length);
console.log(document.getElementsByClassName("sold").length);

Строки — 3, 3 и 1. Три листка делят tag. Все три — элементы p, заголовок — h2, поэтому на этой полке счёт тега совпадает со счётом класса. Только у Evening есть sold. getElementsByClassName(".tag") — другой вызов: точка не входит в имя класса, поэтому длина 0.

Первое совпадение CSS

querySelector возвращает один элемент, первый в порядке документа, или null.

Первое совпадение

javascript
console.log(document.querySelector(".tag").textContent);
console.log(document.querySelector("#shelf .sold").textContent);

Первая строка — Morning. Вторая — Evening. #shelf .sold значит элемент с классом sold внутри полки, а не саму полку. document.getElementById("shelf").querySelector(".sold") начинает поиск с полки и попадает на тот же листок Evening.

Все совпадения, затем индекс

querySelectorAll возвращает каждое совпадение в статической NodeList. Список может быть пустым. Это не null.

Все совпадения

javascript
let tags = document.querySelectorAll(".tag");
console.log(tags.length);
console.log(tags[1].textContent);

Длина — 3. Индекс 1 — это Noon. Индекс 0 — Morning, индекс 2 — Evening. Этот список не растёт, если поздний скрипт добавит листок. HTMLCollection из getElementsByClassName("tag") выросла бы. Один снимок момента, другой остаётся живым.

Имя, которого полка не писала

Спроси id и класс, которых нет в файле.

Ничего не совпало

javascript
console.log(document.getElementById("oven"));
console.log(document.querySelector(".oven"));
console.log(document.querySelectorAll(".oven").length);

Первая строка — null. Вторая — null. Третья — 0. querySelectorAll всё равно возвращает список, когда ничего не совпало: длина 0, а сам список не null. У getElementById нет списка, поэтому промах — это null, не 0.

Строка на странице

Абзац сообщает, сколько листков tag, какой первый и какой листок sold. Скрипт стоит в конце body, когда элементы уже есть. У строки нет класса tag, поэтому она не из этих трёх.

Демо страницы — три листка

html
<!DOCTYPE html>
<html>
<head>
<title>selecting — page</title>
</head>
<body>
<main id="shelf">
<h2 id="loaf">Rye</h2>
<p class="tag">Morning</p>
<p class="tag">Noon</p>
<p class="tag sold">Evening</p>
<p id="line">…</p>
</main>
<script>
let tags = document.querySelectorAll(".tag");
let line = document.getElementById("line");
line.textContent = tags.length + " / " + tags[0].textContent + " / " + document.querySelector(".sold").textContent;
</script>
</body>
</html>

Абзац показывает 3 / Morning / Evening. В этом файле getElementsByTagName("p") считает 4, потому что строка — ещё один p. querySelectorAll(".tag") по-прежнему считает 3. Следующая страница меняет HTML элементов, которые эти вызовы уже нашли.

Проверь полку

  1. Выведи текст заголовка и жди Rye, затем проверку null и жди false
  2. Выведи длину класса, длину p и длину sold: 3, 3 и 1
  3. Выведи текст первого .tag и жди Morning, затем #shelf .sold и жди Evening
  4. Выведи длину querySelectorAll и жди 3, затем индекс 1 и жди Noon
  5. Выведи отсутствующий id и отсутствующий querySelector и оба раза жди null
  6. Выведи querySelectorAll(".oven").length и жди 0
  7. Прочитай абзац и жди 3 / Morning / Evening

Неверный вызов

Страница остаётся открытой. Вызов, который ты написал, попросил другое.

  • Передать .tag в getElementsByClassName; точка принадлежит только селектору CSS
  • Передать tag без точки в querySelector и ждать листки
  • Читать индекс 1 как первый листок
  • Считать промах querySelectorAll значением null, хотя длина 0
  • Считать промах getElementById списком длины 0
  • Считать getElementsByTagName("p") в файле со строкой и ждать 3
  • Вызывать .map у HTMLCollection; это не массив
  • Читать parentElement на этой странице; это была страница дерева

Уносишь с собой

  • getElementById возвращает один элемент или null
  • getElementsByClassName и getElementsByTagName возвращают живую HTMLCollection
  • Метод класса ждёт tag, не .tag
  • querySelector возвращает первое совпадение CSS или null
  • querySelectorAll возвращает статическую NodeList; у промаха длина 0
  • Индекс 0 — Morning, индекс 1 — Noon
  • Следующая страница меняет HTML элементов, которые ты уже выбрал

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
8
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху