Выбор элементов
На полке пекарни один заголовок и три листка. Заголовок говорит 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, не у элемента.
let loaf = document.getElementById("loaf");
console.log(loaf.textContent);
console.log(loaf === null);
Первая строка — Rye. Вторая — false, потому что заголовок на полке есть. Если два элемента делят id loaf, вызов всё равно вернёт только первый в документе.
Имя класса и имя тега
Оба вызова возвращают живую HTMLCollection. Сначала прочитай length, потом бери один листок. Счёт — на полке из четырёх элементов, не в файле со строкой.
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.
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.
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 и класс, которых нет в файле.
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, поэтому она не из этих трёх.
<!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 элементов, которые эти вызовы уже нашли.
Проверь полку
- Выведи текст заголовка и жди Rye, затем проверку null и жди false
- Выведи длину класса, длину
pи длину sold: 3, 3 и 1 - Выведи текст первого
.tagи жди Morning, затем#shelf .soldи жди Evening - Выведи длину
querySelectorAllи жди 3, затем индекс 1 и жди Noon - Выведи отсутствующий id и отсутствующий
querySelectorи оба раза жди null - Выведи
querySelectorAll(".oven").lengthи жди 0 - Прочитай абзац и жди 3 / Morning / Evening
Неверный вызов
Страница остаётся открытой. Вызов, который ты написал, попросил другое.
- Передать
.tagвgetElementsByClassName; точка принадлежит только селектору CSS - Передать
tagбез точки вquerySelectorи ждать листки - Читать индекс 1 как первый листок
- Считать промах
querySelectorAllзначениемnull, хотя длина 0 - Считать промах
getElementByIdсписком длины 0 - Считать
getElementsByTagName("p")в файле со строкой и ждать 3 - Вызывать
.mapуHTMLCollection; это не массив - Читать
parentElementна этой странице; это была страница дерева
Уносишь с собой
getElementByIdвозвращает один элемент илиnullgetElementsByClassNameиgetElementsByTagNameвозвращают живуюHTMLCollection- Метод класса ждёт
tag, не.tag querySelectorвозвращает первое совпадение CSS илиnullquerySelectorAllвозвращает статическуюNodeList; у промаха длина 0- Индекс 0 — Morning, индекс 1 — Noon
- Следующая страница меняет HTML элементов, которые ты уже выбрал
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху