JavaScript – Поиск элементов на странице

В этой статье мы рассмотрим какие в JavaScript существуют методы для выбора элементов на странице, и как с ними работать.
Методы JavaScript для выбора DOM элементов
Работа со страницей так или иначе связана с манипулированием DOM элементами. Но перед тем, как это делать их сначала нужно получить.
Выполняется это в JavaScript посредством специальных методов. Наиболее популярные из них – это querySelectorAll и querySelector. Данные методы осуществляют поиск элементов по CSS селектору.
Их отличие сводится в различии количества возвращаемых DOM элементов. Первый (querySelectorAll
) возвращает все найденные элементы, а второй (querySelector
) – только первый из них.
Кроме них, в DOM API существуют ещё getElementById, getElementsByClassName, getElementsByTagName и getElementsByName. Сейчас они применяются крайне редко, в основном все выполняется через querySelectorAll
и querySelector
.
querySelectorAll – поиск элементов по CSS селектору
querySelectorAll
– применяется, когда нужно найти все элементы по CSS селектору внутри страницы или определённого элемента.
Синтаксис:
// elements1, elements2 – переменные, в которые будут помещены коллекции найденных элементов // поиск внутри всего документа const elements1 = document.querySelectorAll('css_selector'); // поиск внутри элемента (elem) const elements2 = elem.querySelectorAll('css_selector');
В приведённом коде css_selector
– это строка, содержащая CSS селектор, в соответствии с которым необходимо осуществить поиск элементов.
querySelectorAll
возвращает все найденные элементы в виде статической коллекции типа NodeList
.
Статическая коллекция — это такая, которая не изменяется, если после вызова этого метода на странице появились новые элементы, подходящие под указанный CSS селектор. В этом случае, чтобы в сформированную коллекцию попали новые элементы их выбор нужно выполнить заново.
Узнать количество элементов в коллекции можно с помощью свойства length
:
// выберем все элементы с type="submit" на странице const submitList = document.querySelectorAll('[type="submit"]'); // узнаем количество найденных элементов const submitLength = submitList.length;
Обратиться к определённому элементу в коллекции можно по его индексу. Индексы начинаются с 0.
// получим первый элемент из submitList const submit1 = submitList[0]; // получим второй элемент из submitList const submit2 = submitList[1];
В этом случае возвращается DOM элемент находящийся под указанным индексом в коллекции или undefined
, если элемента с таким индексом нет.
Перебрать коллекцию выбранных элементов можно с помощью цикла for:
// получим все элементы p на странице const paragraphList = document.querySelectorAll('p'); // переберём полученную коллекцию элементов с помощью цикла for for (let i=0, length = paragraphList.length; i < length; i++) { // paragraphList[i] - i-ый элемент }
Перебор элементов посредством цикла for...of:
// например, переберём все элементы html страницы (в CSS для выбора всех элементов используется символ *) // выберем все изображения на странице const all = document.querySelectorAll('*'); // выведем все найденные DOM элементы в консоль for (let elem of all) { console.log(elem); }
Примеры
1. Выполним проверку существование элементов с атрибутом data-toggle="modal"
:
if (document.querySelectorAll('[data-toggle="modal"]').length) { // на странице данные элементы есть в наличии }
2. Найти все элементы <a>
внутри элемента <ul>
с классом nav
:
const anchors = document.querySelectorAll('ul.nav a');
querySelector – выбор элемента по CSS селектору
querySelector
– это метод, который также как querySelectorAll
осуществляет поиск по CSS селектору, но в отличие от него возвращает не все найденные элементы, а только первый из них.
Синтаксис:
// поиск внутри всего документа var element = document.querySelector('selector'); // поиск внутри конкретного элемента (elem) var element = elem.querySelector('selector');
В приведённом коде selector
– это строка, содержащая CSS селектор, в соответствии с которым необходимо найти элемент.
Результат метода querySelector
аналогичен elem.querySelectorAll('selector')[0]
, но в отличие от него он выполняет это намного быстрее. Это происходит потому, что querySelector
сразу же останавливает процесс поиска, как только находит соответствующий элемент. В то время как elem.querySelectorAll('selector')[0]
сначала находит все элементы, и только после того как он все их нашёл мы уже можем обратиться к этим элементам и с помощью оператора доступа (квадратные скобки) взять первый из них.
В качестве результата метод querySelector
возвращает ссылку на объект типа Element
или null
(если элемент не найден).
Примеры
1. Обратиться к элементу по id
, значение которого равно pagetitle
:
var pagetitle = document.querySelector('#pagetitle');
2. Выполнить поиск элемента по классу nav
:
var el = document.querySelector('.nav');
3. Обратиться к элементу <h3>
, находящемуся в теге <div>
с классом comments
, который в свою очередь расположен в <main>
:
var header = document.querySelector('main div.comments h3');
4. Проверить наличие элемента с классом modal
на странице:
if (document.querySelector('.modal')) { // элемент .modal существует }
«Старые» методы для выбора элементов
К данной категории относятся методы, которые сейчас практически не применяются для поиска элементов. Их в основном можно встретить в «старом» коде.
getElementById
– предназначен для получения элемента поid
(идентификатору);getElementsByClassName
– используется, когда нужно найти элемент по одному или нескольким классам;getElementsByTagName
– применяется для выбора элементов по тегу;getElementsByName
– прибегают, когда следует обратиться к элементам по атрибутуname
.
getElementById – получение элемента по значению id
Например:
<div id="main">...</div> ... <script> // получим элемент и сохраним ссылку на него в переменную main var main = document.getElementById('main'); </script>
В качестве результата метод getElementById
возвращает ссылку на объект типа Element
или значение null
, если элемент с указанным идентификатором не найден.
Метод getElementById
имеется только у объекта document
.
Указания значения id
необходимо выполнять с учётом регистра, т.к., например, main
и Main
– это разные значения.
Кроме этого, в соответствии со стандартом в документе не может быть несколько элементов с одинаковым значением атрибута id
, т.к. значение идентификатора должно быть уникальным.
Тем не менее, если вы допустили ошибку и в документе существуют несколько элементов с одинаковым id
, то метод getElementById
более вероятно вернёт первый элемент, который он встретит в коде (DOM). Но на это полагаться нельзя, т.к. такое поведение не прописано в стандарте.
Например, получим элемент, имеющий в качестве id
значение pagetitle
:
<h1 id="pagetitle">Название статьи</h1> ... <script> // получим элемент, имеющий id="pagetitle" var pagetitle = document.getElementById('pagetitle'); </script>
Действие метода getElementById
можно очень просто выполнить с помощью querySelector
:
// получение элемента #nav через getElementById var nav = document.getElementById('nav'); // получение элемента #nav через querySelector var nav = document.querySelector('#nav');
getElementsByClassName – получение списка элементов по именам классов
Этот метод позволяет найти все элементы с указанными классами во всём документе или в некотором элементе. В первом случае его необходимо вызывать у document
, а во втором – у элемента, внутри которого вы хотите их получить.
Синтаксис:
// внутри всего документа var elements = document.getElementsByClassName(names); // внутри некоторого элемента (someElement) var elements = someElement.getElementsByClassName(names);
- в переменную
elements
будет помещена живая коллекция (HTMLCollection
) найденных элементов; - в
names
необходимо задать строку, состоящую из одного или нескольких классов разделённых между собой с помощью пробела.
Например, получим все элементы с классом btn
, которые имеются на странице:
var btns = document.getElementsByClassName('btn');
Метод getElementsByClassName
позволяет искать элементы не только по одному имени класса, но и по нескольким, которые должны быть у элемента.
Например, выберем элементы на странице у которых имеются классы btn
и btn-danger
:
var elements = document.getElementsByClassName('btn btn-danger');
Функция getElementsByClassName
позволяет искать элементы не только внутри всего документа, но и в конкретном элементе.
Например, найти все элементы с классом code
, расположенные внутри элемента #main
:
// получение элемента с id='main' var main = document.getElementsById('main'); // получим все элементы с классом code, расположенные в #main var codes = main.getElementsByClassName('code');
Выполнить эту задачу с помощью querySelectorAll
можно более эффективно:
var codes = document.querySelectorAll('#main .code');
getElementsByTagName – получение элементов по имени тега
Метод getElementsByTagName
предназначен для получения коллекции элементов по имени тега.
Синтаксис:
// внутри всего документа var elements = element.getElementsByTagName(tagName); // внутри некоторого элемента (someElement) var elements = someElement.getElementsByTagName(tagName);
tagName
- это аргумент, который должен содержать строку с названием тега, который нужно найти. Название тега необходимо указывать с помощью прописных букв. Чтобы выбрать все элементы можно использовать символ *
.
Например, получить коллекцию элементов <li>
, находящихся в элементе с id="aside__nav"
:
// получим элемент с id="aside__nav" var asideNav = element.getElementById('aside__nav'); // получим li расположенные внутри элемента asideNav var elements = asideNav.getElementsByTagName('li');
Этот пример через querySelectorAll
можно решить так:
var elements = document.querySelectorAll('#aside__nav li');
getElementsByName – получение элементов по значению атрибута name
Метод getElementsByName
может применяться, когда вам нужно выбрать элементы, имеющие атрибут name
с указанным значением.
Синтаксис:
// внутри всего документа var elements = element.getElementsByName(name); // внутри некоторого элемента (someElement) var elements = someElement.getElementsByName(name);
name
- это аргумент, содержащий строку со значением атрибута name
в соответствии с которым нужно найти элементы.
Например, выбрать все элементы на странице с name="phone"
:
var phoneList = document.getElementsByName('phone');
Реализовать это с querySelectorAll
можно следующим образом:
var phoneList = document.querySelectorAll('[name="phone"]');
getElementsBy* и живые коллекции
Методы getElementsBy*
в отличие от querySelectorAll
возвращают живую коллекцию элементов. Т.е. коллекцию содержимое которой может изменяться при изменении DOM. Рассмотрим это на примере.
В этом примере получим элементы li
находящиеся в #list
и выведем их количество в консоль. Затем через 5 секунд программно добавим ещё один элемент li
в #list
и ещё раз возвратим их количество в консоль.
<ul id="list"> <li>...</li> <li>...</li> </ul> <script> var // выберем элемент #list list = document.getElementById('list'), // получим живую коллекцию elements состоящую из элементов li, расположенных в list elements = list.getElementsByTagName('LI'); // выведем количество элементов в коллекции elements в консоль console.log('Количество элементов в list: ' + elements.length); // 2 // выполним код через 5 секунд setTimeout(function () { // cоздадим элемент li с контентом "..." var li = document.createElement('LI'); li.textContent = '...'; // добавим его в #list list.append(li); // выведем количество элементов в коллекции elements в консоль console.log('Количество элементов в list: ' + elements.length); // 3 }, 5000); </script>
Как вы видите, эта коллекция элементов является живой, т.е. она автоматически изменяется. Сначала в ней было 2 элемента, а после того, как мы на страницу добавили ещё один подходящий элемент, в ней их стало 3.
Если тоже выполнить с помощью querySelectorAll
, то мы увидим, что в ней находится статическая (не живая) коллекция элементов.
<ul id="list"> <li>...</li> <li>...</li> </ul> <script> var // выберем элемент #list list = document.getElementById('list'), // получим статичную коллекцию elements состоящую из элементов li, расположенных в list elements = list.querySelectorAll('li'); // выведем количество элементов в коллекции elements в консоль console.log('Количество элементов в list: ' + elements.length); // 2 // выполним код через 5 секунд setTimeout(function () { // cоздадим элемент li с контентом "..." var li = document.createElement('LI'); li.textContent = '...'; // добавим его в #list list.append(li); // выведем количество элементов в коллекции elements в консоль console.log('Количество элементов в list: ' + elements.length); // 2 }, 5000); </script>
Как вы видите количество элементов в коллекции не изменилось.
Если вам нужно обновить статическую коллекцию элементов после изменения DOM, то метод querySelectorAll
нужно вызвать ещё раз.
<ul id="list"> <li>...</li> <li>...</li> </ul> <script> var // выберем элемент #list list = document.getElementById('list'), // получим статичную коллекцию elements состоящую из элементов li, расположенных в list elements = list.querySelectorAll('li'); // выведем количество элементов в коллекции elements в консоль console.log('Количество элементов в list: ' + elements.length); // 2 // выполним код через 5 секунд setTimeout(function () { // cоздадим элемент li с контентом "..." var li = document.createElement('LI'); li.textContent = '...'; // добавим его в #list list.append(li); // получим статичную коллекцию elements состоящую из элементов li, расположенных в list elements = list.querySelectorAll('li'); // выведем количество элементов в коллекции elements в консоль console.log('Количество элементов в list: ' + elements.length); // 3 }, 5000); </script>
Итого
В JavaScript можно выделить 6 основных методов для выбора элементов на странице.
Некоторые из них можно использовать для поиска одних элементов внутри других. Среди них: querySelector
, querySelectorAll
, getElementsByTagName
, getElementsByClassName
. Другие (getElementById
и getElementsByName
) можно применять только для выбора элементов в пределах всей страницы (document
).
Кроме этого, их можно ещё дополнительно разделить на 2 группы. К первой группе можно отнести методы, которые возвращают статическую коллекцию элементов. Это querySelector
, querySelectorAll
и getElementById
. Ко второй те методы, которые возвращаю живую коллекцию. Это getElementsByTagName
, getElementsByClassName
и getElementsByName
.
Дополнительные материалы
matches – проверка на соответствие элемента CSS селектору
matches
– это метод, который проверяет соответствует элемент, для которого он вызывается указанному CSS селектору. Если соответствует, то возвращает true
. В противном случае false
.
Синтаксис:
var result = element.matches(selector);
Ранее, в «старых» браузерах данный метод имел название matchesSelector
, а также поддерживался с префиксами.
Чтобы обеспечить поддержку данного метода большим количеством браузеров можно использовать следующий полифилл:
if (!Element.prototype.matches) { Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector; }
Например, выберем все элементы <li>
расположенные внутри элемента с id="questions"
, а затем удалим из них те, которые соответствуют селектору .answered
:
// выберем все элементы <li> находящиеся в #questions var questions = document.querySelectorAll('#questions > li'); // переберём выбранные элементы с помощью цикла for for (var i = 0, len = questions.length; i < len; i++) { // если элемент можно получить с помощью селектора .answered, то... if (questions[i].matches('.answered')) { // удаляем его questions[i].remove(); } }
closest – поиск ближайшего предка по CSS селектору
closest
– это метод, который позволяет найти ближайшего предка для элемента в соответствии с указанным селектором. При этом поиск предков начинается с самого элемента, для которого данный метод вызывается и если он будет ему соответствовать, то closest
вернёт сам этот элемент.
Синтаксис:
var parent = someElement.closest(selector);
В приведённом коде selector
– это строка, содержащая селектор, в соответствии с которым необходимо найти ближайшего предка для someElement
.
В качестве результата метод closest
возвращает найденный DOM-элемент или null
(если соответствующий элемент найден не был).
Например, найдем для некоторого элемента ближайшего предка по селектору .parent
:
<div class="parent"> <div class="wrapper"> <div id="child">...</div> </div> </div> <script> var child = document.querySelector('#child'); var parent = child.closest('.parent'); // closest вернёт <div class="parent"> </script>
contains – проверка наличия одного элемента внутри другого
contains
– это метод, посредством которого можно проверить существование одного элемента внутри другого.
Синтаксис:
var result = element1.contains(element2);
В приведённом коде result
– это переменная, в которую поместится значение true
или false
в зависимости от того имеется ли element2
внутри element1
.
Например:
<div id="parent"> <div id="child">...</div> </div> <script> var parent = document.querySelector('#parent'); var child = document.querySelector('#child'); var result = parent.contains(child); // true </script>
Задачи
Имеется страница. В ней следует выбрать:
Навела на мысль, что поиск соседних элементов у родителя можно сделать ещё проще. И самое приятное, что работает!
Долгое время не занимался темой, порядком подзабыл некоторые детали, тут прямо как раз то, что нужно.