Поиск: getElement*, querySelector*
Свойства навигации по DOM хороши, когда элементы расположены рядом. А что, если нет? Как получить произвольный элемент страницы?
Для этого в DOM есть дополнительные методы поиска.
document.getElementById или просто id
Если у элемента есть атрибут id , то мы можем получить его вызовом document.getElementById(id) , где бы он ни находился.
Также есть глобальная переменная с именем, указанным в id :
…Но это только если мы не объявили в JavaScript переменную с таким же именем, иначе она будет иметь приоритет:
Пожалуйста, не используйте такие глобальные переменные для доступа к элементам
Это поведение соответствует стандарту, но поддерживается в основном для совместимости, как осколок далёкого прошлого.
Браузер пытается помочь нам, смешивая пространства имён JS и DOM. Это удобно для простых скриптов, которые находятся прямо в HTML, но, вообще говоря, не очень хорошо. Возможны конфликты имён. Кроме того, при чтении JS-кода, не видя HTML, непонятно, откуда берётся переменная.
В этом учебнике мы будем обращаться к элементам по id в примерах для краткости, когда очевидно, откуда берётся элемент.
В реальной жизни лучше использовать document.getElementById .
Значение id должно быть уникальным
Значение id должно быть уникальным. В документе может быть только один элемент с данным id .
Если в документе есть несколько элементов с одинаковым значением id , то поведение методов поиска непредсказуемо. Браузер может вернуть любой из них случайным образом. Поэтому, пожалуйста, придерживайтесь правила сохранения уникальности id .
Только document.getElementById , а не anyElem.getElementById
Метод getElementById можно вызвать только для объекта document . Он осуществляет поиск по id по всему документу.
querySelectorAll
Самый универсальный метод поиска – это elem.querySelectorAll(css) , он возвращает все элементы внутри elem , удовлетворяющие данному CSS-селектору.
Этот метод действительно мощный, потому что можно использовать любой CSS-селектор.
Псевдоклассы тоже работают
Псевдоклассы в CSS-селекторе, в частности :hover и :active , также поддерживаются. Например, document.querySelectorAll(‘:hover’) вернёт коллекцию (в порядке вложенности: от внешнего к внутреннему) из текущих элементов под курсором мыши.
querySelector
Метод elem.querySelector(css) возвращает первый элемент, соответствующий данному CSS-селектору.
Иначе говоря, результат такой же, как при вызове elem.querySelectorAll(css)[0] , но он сначала найдёт все элементы, а потом возьмёт первый, в то время как elem.querySelector найдёт только первый и остановится. Это быстрее, кроме того, его короче писать.
matches
Предыдущие методы искали по DOM.
Метод elem.matches(css) ничего не ищет, а проверяет, удовлетворяет ли elem CSS-селектору, и возвращает true или false .
Этот метод удобен, когда мы перебираем элементы (например, в массиве или в чём-то подобном) и пытаемся выбрать те из них, которые нас интересуют.
. .
closest
Предки элемента – родитель, родитель родителя, его родитель и так далее. Вместе они образуют цепочку иерархии от элемента до вершины.
Метод elem.closest(css) ищет ближайшего предка, который соответствует CSS-селектору. Сам элемент также включается в поиск.
Другими словами, метод closest поднимается вверх от элемента и проверяет каждого из родителей. Если он соответствует селектору, поиск прекращается. Метод возвращает либо предка, либо null , если такой элемент не найден.
getElementsBy*
Существуют также другие методы поиска элементов по тегу, классу и так далее.
На данный момент, они скорее исторические, так как querySelector более чем эффективен.
Здесь мы рассмотрим их для полноты картины, также вы можете встретить их в старом коде.
- elem.getElementsByTagName(tag) ищет элементы с данным тегом и возвращает их коллекцию. Передав «*» вместо тега, можно получить всех потомков.
- elem.getElementsByClassName(className) возвращает элементы, которые имеют данный CSS-класс.
- document.getElementsByName(name) возвращает элементы с заданным атрибутом name . Очень редко используется.
// получить все элементы div в документе let divs = document.getElementsByTagName('div');
Давайте найдём все input в таблице:
Ваш возраст:
let inputs = table.getElementsByTagName('input'); for (let input of inputs)
Не забываем про букву «s» !
Одна из самых частых ошибок начинающих разработчиков (впрочем, иногда и не только) – это забыть букву «s» . То есть пробовать вызывать метод getElementByTagName вместо getElementsByTagName .
Буква «s» отсутствует в названии метода getElementById , так как в данном случае возвращает один элемент. Но getElementsByTagName вернёт список элементов, поэтому «s» обязательна.
Возвращает коллекцию, а не элемент!
Другая распространённая ошибка – написать:
// не работает document.getElementsByTagName('input').value = 5;
Попытка присвоить значение коллекции, а не элементам внутри неё, не сработает.
Нужно перебрать коллекцию в цикле или получить элемент по номеру и уже ему присваивать значение, например, так:
// работает (если есть input) document.getElementsByTagName('input')[0].value = 5;
Ищем элементы с классом .article :
Живые коллекции
Все методы «getElementsBy*» возвращают живую коллекцию. Такие коллекции всегда отражают текущее состояние документа и автоматически обновляются при его изменении.
В приведённом ниже примере есть два скрипта.
- Первый создаёт ссылку на коллекцию . На этот момент её длина равна 1 .
- Второй скрипт запускается после того, как браузер встречает ещё один , теперь её длина – 2 .
First div Second div
Напротив, querySelectorAll возвращает статическую коллекцию. Это похоже на фиксированный массив элементов.
Если мы будем использовать его в примере выше, то оба скрипта вернут длину коллекции, равную 1 :
First div Second div
Теперь мы легко видим разницу. Длина статической коллекции не изменилась после появления нового div в документе.
Итого
Есть 6 основных методов поиска элементов в DOM:
| Метод | Ищет по. | Ищет внутри элемента? | Возвращает живую коллекцию? |
| querySelector | CSS-selector | ✔ | — |
| querySelectorAll | CSS-selector | ✔ | — |
| getElementById | id | — | — |
| getElementsByName | name | — | ✔ |
| getElementsByTagName | tag or ‘*’ | ✔ | ✔ |
| getElementsByClassName | class | ✔ | ✔ |
Безусловно, наиболее часто используемыми в настоящее время являются методы querySelector и querySelectorAll , но и методы getElement(s)By* могут быть полезны в отдельных случаях, а также встречаются в старом коде.
- Есть метод elem.matches(css) , который проверяет, удовлетворяет ли элемент CSS-селектору.
- Метод elem.closest(css) ищет ближайшего по иерархии предка, соответствующему данному CSS-селектору. Сам элемент также включён в поиск.
И, напоследок, давайте упомянем ещё один метод, который проверяет наличие отношений между предком и потомком:
- elemA.contains(elemB) вернёт true , если elemB находится внутри elemA ( elemB потомок elemA ) или когда elemA==elemB .
Задачи
Поиск элементов
важность: 4
Вот документ с таблицей и формой.
- Таблицу с id=»age-table» .
- Все элементы label внутри этой таблицы (их три).
- Первый td в этой таблице (со словом «Age»).
- Форму form с именем name=»search» .
- Первый input в этой форме.
- Последний input в этой форме.
Откройте страницу table.html в отдельном окне и используйте для этого браузерные инструменты разработчика.
Есть много путей как это сделать.
// 1. Таблица с `id="age-table"`. let table = document.getElementById('age-table') // 2. Все label в этой таблице table.getElementsByTagName('label') // или document.querySelectorAll('#age-table label') // 3. Первый td в этой таблице table.rows[0].cells[0] // или table.getElementsByTagName('td')[0] // или table.querySelector('td') // 4. Форма с name="search" // предполагаем, что есть только один элемент с таким name в документе let form = document.getElementsByName('search')[0] // или, именно форма: document.querySelector('form[name="search"]') // 5. Первый input в этой форме form.getElementsByTagName('input')[0] // или form.querySelector('input') // 6. Последний input в этой форме let inputs = form.querySelectorAll('input') // найти все input inputs[inputs.length-1] // взять последний
DOM — Поиск элементов
В этой главе рассказывается, как найти и получить доступ к HTML элементам на HTML странице.
Поиск HTML элементов
Часто в JavaScript необходимо проводить определенные манипуляции с HTML элементами.
Чтобы это сделать, сначала нужно найти требуемый элемент. Найти HTML элемент можно несколькими способами:
- по идентификатору id
- по имени тега
- по имени класса
- по селекторам CSS
- по наборам объектов HTML
Поиск HTML элемента по идентификатору
Самый простой способ найти HTML элемент в DOM — это использовать его идентификатор id.
В следующем примере мы ищем элемент с id=»intro»:
var myElement = document.getElementById("intro");
Если элемент будет найден, то он будет возвращен в виде объекта (в переменную myElement).
Если элемент не будет найден, то в переменная myElement будет содержать значение null.
Поиск HTML элемента по имени тега
В следующем примере мы ищем все элементы
:
var x = document.getElementsByTagName("p");
В следующем примере сначала происходит поиск элемента с id=»main», а затем всех элементов
внутри «main»:
var x = document.getElementById("main"); var y = x.getElementsByTagName("p");
Поиск HTML элемента по имени класса
Если нужно найти все HTML элементы с одним и тем же именем класса, то используют метод getElementsByClassName().
В следующем примере возвращается список всех элементов с атрибутом class=»intro»:
var x = document.getElementsByClassName("intro");
Внимание! Поиск элементов по имени класса не работает в Internet Explorer 8 и более ранних версиях.
Поиск HTML элемента по CSS селекторам
Если нужно найти все HTML элементы, подходящие по заданному CSS селектору (id, имена классов, типы, атрибуты, значения атрибутов и т.п.), используется метод querySelectorAll().
В следующем примере возвращается список всех элементов
с атрибутом :
var x = document.querySelectorAll("p.intro");
Внимание! Метод querySelectorAll() не работает в Internet Explorer 8 и более ранних версиях.
Поиск HTML элемента по наборам HTML объектов
В следующем примере производится поиск элемента формы с атрибутом в наборе объектов forms, и отображаются все значения элементов:
var x = document.forms["frm1"]; var text = ""; var i; for (i = 0; i < x.length; i++) < text += x.elements[i].value + "
"; > document.getElementById("demo").innerHTML = text;
Также доступны следующие HTML объекты (и наборы объектов):
- document.anchors
- document.body
- document.documentElement
- document.embeds
- document.forms
- document.head
- document.images
- document.links
- document.scripts
- document.title
Как искать элементы в dom дереве
На чём стоят три слона, на которых держится веб?
Время чтения: меньше 5 мин
Открыть/закрыть навигацию по статье
Контрибьюторы:
Обновлено 6 октября 2022
Кратко
Скопировать ссылку «Кратко» Скопировано
DOM (Document Object Model) — это специальная древовидная структура, которая позволяет управлять HTML-разметкой из JavaScript-кода. Управление обычно состоит из добавления и удаления элементов, изменения их стилей и содержимого.
Браузер создаёт DOM при загрузке страницы, складывает его в переменную document и сообщает, что DOM создан, с помощью события DOM Content Loaded . С переменной document начинается любая работа с HTML-разметкой в JavaScript.
Как пишется
Скопировать ссылку «Как пишется» Скопировано
Объект document содержит большое количество свойств и методов, которые позволяют работать с HTML. Чаще всего используются методы, позволяющие найти элементы страницы.
Свойства
Скопировать ссылку «Свойства» Скопировано
- title — заголовок документа. Браузер обычно показывает его на вкладке.
Установить свой заголовок можно простым присваиванием:
document.title = 'Мое название документа'console.log(document.title)// Мое название документаdocument.title = 'Мое название документа' console.log(document.title) // Мое название документа
- forms — получить список форм на странице. Свойство только для чтения, напрямую перезаписать его нельзя.
- body — получить элемент страницы.
- head — получить элемент страницы.
Методы
Скопировать ссылку «Методы» Скопировано
- get Element By Id — поиск элемента по идентификатору;
- get Elements By Class Name — поиск элементов по названию класса;
- get Elements By Tag Name — поиск элементов по названию тега;
- query Selector — поиск первого элемента, подходящего под CSS-селектор;
- query Selector All — поиск всех элементов подходящих под CSS-селектор.
Как понять
Скопировать ссылку «Как понять» Скопировано
Браузер создаёт DOM на основе HTML-кода страницы. Затем на основе DOM и других структур, браузер рисует страницу пользователю. При изменении DOM, браузер анализирует это и обновляет страницу.
DOM и страница, которую видит пользователь, связаны. Если изменишь одно, то изменится и второе:
- пользователь заполняет форму — можно прочитать введённые значения в DOM;
- при выборе страны, мы заполняем список городов в DOM — пользователь видит список.
Высокоуровневая схема такого взаимодействия:

Из чего состоит DOM
Скопировать ссылку «Из чего состоит DOM» Скопировано
HTML страница — это теги, вложенные друг в друга. Например:
Браузер превращает эту разметку в JavaScript представление, сохраняя при этом вложенность и свойства каждого HTML-элемента. Этого удаётся достичь с помощью специальной структуры данных — дерева.
Каждый тег представляет собой узел дерева. У каждого узла могут быть дочерние узлы — таким образом сохраняется информация о вложенности тегов. Правда, слово тег в этом контексте не используют и говорят элемент. Например, HTML-код выше превратится в такое дерево:

Дерево состоит из обычных и текстовых узлов. Обычные узлы — это HTML-теги, а текстовые узлы — текст внутри тегов.
Обычный узел называется Element , и он содержит в себе описание тега, атрибутов тега и обработчиков. Если изменить описание — изменится и HTML-код этого элемента (возможно что-то даже изменится на экране. Например, если поменять цвет шрифта). В статье Element мы разбираем всё необходимое для работы с элементами.
У любого узла есть один родительский узел и дочерние. Родительский узел — элемент, в который вложен текущий узел, он может быть только один. Дочерние — узлы, которые вложены в текущий узел.
Это правило не работает только в двух случаях:
- корневой узел — у такого узла нет родителя;
- текстовый узел — у таких узлов нет дочерних узлов, только родитель. Последний уровень любого DOM-дерева состоит из текстовых узлов.
На практике
Скопировать ссылку «На практике» Скопировано
Николай Лопин советует
Скопировать ссылку «Николай Лопин советует» Скопировано
Напрямую с DOM работают редко. Обычно работают на уровне элементов.
Из-за своей древовидной структуры искать элементы по DOM можно не только от корня. В диаграмме выше можно найти сначала элемент ul , а затем искать элементы среди его потомков.
let ulElement = document.getElementsByTagName('ul')[0]// среди потомков ul нашли последний lilet lastLi = ulElement.querySelector('li:last-child') lastLi.style.color = 'red'let ulElement = document.getElementsByTagName('ul')[0] // среди потомков ul нашли последний li let lastLi = ulElement.querySelector('li:last-child') lastLi.style.color = 'red'
Методы поиска элементов в DOM
На этом занятии рассмотрим методы поиска произвольных элементов в HTML-документе. Рассмотренные свойства на предыдущем занятии по навигации DOM-дереву хороши если элементы расположены рядом. Но что делать, если требуемый объект может находиться в самых разных местах. Как его искать? Вот об этом и пойдет сейчас речь.
В самом простом случае мы можем у любого тега HTML-документа прописать атрибут id с некоторым уникальным значением. Например:
DOCTYPE html> html> head> title>Уроки по JavaScripttitle> head> body> div id="div_id"> p>Текст внутри блока div div> script> script> body> html>
Здесь у нас тег div имеет атрибут id со значением div_id. Мы это значение придумываем сами, главное, чтобы оно было уникальным в пределах HTML-страницы. Теперь можно получить этот элемент div по этому id, где бы он ни находился в DOM-дереве. Для этого используется метод getElementById объекта document:
let divElem = document.getElementById('div_id'); console.log( divElem );
Мы в методе getElementById в качестве аргумента указываем строку со значением атрибута id и на выходе получаем ссылку на этот элемент.
Или же можем получить доступ к этому элементу напрямую через глобальную переменную div_id, которая автоматически создается браузером при формировании DOM-дерева:
console.log( div_id );
Но этот второй способ имеет одну уязвимость: если мы создадим в скрипте переменную с таким же именем, то прежнее значение div_id будет затерто:
let div_id = "не тег div";
так что этот подход следует применять с большой осторожностью, лучше использовать метод getElementById.
В стандарте ES6+ появился новый метод поиска элементов querySelectorAll, который возвращает список элементов, удовлетворяющих CSS-селектору, который мы в нем указываем.
Например, добавим в HTML-документ вот такой маркированный список:
ul> li>Солнце li>Меркурий li>Венера li>Земля li>Марс ul>
и вот такой нумерованный список:
p>Звезды: ol> li>Сириус li>Альдебаран li>Капелла li>Ригель ol>
let list = document.querySelectorAll("ul > li"); for(let val of list) console.log(val);
Как видите, у нас были выбраны элементы только маркированного списка. Мало того, в методе querySelectorAll можно использовать псевдоклассы для указания более сложных CSS-селекторов, например, так:
let list = document.querySelectorAll("ul > li:first-child");
тогда мы увидим только первый элемент списка. И так далее. С помощью querySelectorAll можно довольно просто выбрать нужные элементы и далее производить с ними необходимые действия.
Если же нам нужно по определенному CSS-селектору найти только первый подходящий элемент, то для этого применяется другой метод querySelector:
let element = document.querySelector("ol > li"); console.log(element);
let element = document.querySelectorAll("ol > li")[0];
но это будет работать медленнее, так как все равно сначала будут находиться все подходящие элементы, а затем, браться первый. Поэтому, если нужно найти только первый подходящий, то следует использовать querySelector.
Следующий метод matches позволяет определить: подходит ли данный элемент под указанный CSS-селектор или нет. Если подходит, то возвращает true, иначе – false. Например, создадим такое оглавление:
h1>О звездахh1> div class="content-table"> ul class="stars-list"> li class="star">О сириусеli> li class="star">Об альдебаранеli> li class="contact">Обратная связьli> ul> div>
И мы, перебирая список пунктов меню, хотим выбрать только те элементы, у которых class равен star. Это можно сделать так:
let list = document.querySelectorAll("ul.stars-list > li"); for(let item of list) { if(item.matches("li.star")) console.log(item); }
Обратите внимание, что метод matches относится к объекту DOM, а не к document. Что, в общем-то логично, так как нам нужно проверить конкретный элемент на соответствие CSS-селектора. В результате, в консоле мы увидим первые два элемента:
li class="star">О сириусеli> li class="star">Об альдебаранеli>
Следующий метод elem.closest(css) ищет ближайшего предка, который соответствует CSS-селектору. Сам элемент также включается в поиск. Метод возвращает либо предка, либо null, если такой элемент не найден. Например:
let li = document.querySelector("li.star"); console.log(li.closest('.stars-list')); console.log(li.closest('.content-table')); console.log(li.closest('h1')); // null
Сначала мы выбираем первый элемент li пункта меню. Затем, с помощью метода closest ищем ближайшего родителя с классом stars-list. Находится список ul. Далее, ищем родителя с классом content-table. Находим блок div. Наконец, пытаемся найти родителя с тегом h1. Но его нет, так как h1 в документе не является родителем для объекта li. Получаем значение null.
- elem.getElementsByTagName(tag) ищет элементы с указанным тегом и возвращает их коллекцию. Указав «*» вместо тега, можно получить всех потомков.
- elem.getElementsByClassName(className) возвращает элементы, которые имеют указанный CSS-класс.
- document.getElementsByName(name) возвращает элементы с заданным атрибутом name. (Используется очень редко).
DOCTYPE html> html> head> title>Уроки по JavaScripttitle> head> body> h1>О звездахh1> h2>Об альдебаранеh2> script> let list = document.getElementsByTagName("h2"); script> h2>О ригелеh2> script> for(let item of list) console.log(item); script> body> html>
Мы в консоле увидим список из двух тегов h2, хотя когда этот список формировался в HTML-документе был всего один тег h2. Второй добавился позже, автоматически. Но, если мы будем получать список этих элементов с помощью метода querySelectorAll:
let list = document.querySelectorAll("h2");
то увидим только один тег h2. Так как здесь делается как бы снимок коллекции на текущий момент состояния HTML-документа и после этого никак не меняется. Вот этот момент при работе с этими методами следует иметь в виду. Ну и в заключение этого занятия отметим еще один полезный метод
elemA.contains(elemB)
который возвращает значение true, если elemB является дочерним по отношению к elemA. И false в противном случае. Например, вот в этом документе:
div class="content-table"> ul class="stars-list"> li class="star">О сириусеli> li class="star">Об альдебаранеli> li class="contact">Обратная связьli> ul> div>
Можно проверить: имеется ли список внутри тега div:
let div = document.querySelector("div.content-table"); let ul = document.querySelector("ul.stars-list"); if(div.contains(ul)) console.log("ul внутри div");