В этой статье мы рассмотрим какие в JavaScript имеются методы для выбора элементов на странице, а также как с ними работать.

Методы для выбора DOM элементов

Работа со страницей так или иначе связана с манипулированием DOM элементами. Но для того, чтобы с этими элементами работать их необходимо сначала выбрать или получить.

Для этого в JavaScript имеются специальные предназначенные для выполнения этих действий методы. Наиболее часто используемые из них – это querySelectorAll и querySelector. Они выполняют поиск элементов в DOM по CSS-селектору. Они отличаются друг от друга только тем, что querySelectorAll возвращает все найденные элементы, а querySelector - только первый из них.

Кроме этого, в API DOM имеются ещё другие методы для выбора элементов. Это getElementById, getElementsByClassName, getElementsByTagName, getElementsByName. Но сейчас они используются крайне редко, т.к. их действия можно очень просто выполнить с помощью querySelectorAll и querySelector.

querySelectorAll – выбор элементов по CSS селектору

querySelectorAll – это метод, который позволяет найти все элементы по CSS селектору внутри всей страницы или конкретного элемента, для которого он вызывается.

Синтаксис:

// выбор элементов внутри документа с последующим их сохранением в переменную elements
var elements = document.querySelectorAll('selector');
// нахождение всех элементов внутри elem, удовлетворяющих selector
var elements = elem.querySelectorAll('selector');

В приведённом выше коде selector – это строковый аргумент, представляющий собой CSS селектор, в соответствии с которым нужно найти элементы.

Метод querySelectorAll возвращает все найденные элементы в виде статической коллекции типа NodeList.

Статическая коллекция — это такая, которая не изменяется, если после вызова этого метода на странице появятся новые элементы, подходящие под указанный CSS селектор. Таким образом, если вам необходимо обновить полученную коллекцию после изменения DOM-страницы, то её следует просто сформировать, заново вызвав этот метод с указанным селектором ещё раз.

Узнать количество элементов в коллекции можно с помощью свойства length:

// выберем все элементы с type="submit" на странице
var submitList = document.querySelectorAll('[type="submit"]');
// узнаем количество найденных элементов
var submitLength = submitList.length;

Обратиться к определённому элементу в коллекции можно по его индексу. Индексы начинаются с 0.

// получим первый элемент из submitList
var submit1 = submitList[0];
// получим второй элемент из submitList
var submit2 = submitList[1];

В этом случае возвращается DOM элемент находящийся под указанным индексом в коллекции или undefined, если элемента с таким индексом нет.

Перебрать коллекцию выбранных элементов можно с помощью цикла for:

// получим все элементы p на странице
var paragraphList = document.querySelectorAll('p');
// переберём полученную коллекцию элементов с помощью цикла for
for (var i=0, length = paragraphList.length; i < length; i++) {
  // paragraphList[i] - i-ый элемент
}

Перебор элементов посредством цикла for...of:

// например, переберём все элементы html страницы (в CSS для выбора всех элементов используется символ *)
// выберем все изображения на странице
var 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:

var 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>

Задачи

Имеется страница. В ней следует выбрать:

  • последний элемент с классом article, расположенный в <main> (решение);
  • все элементы .section, находящиеся в .aside кроме 2 второго (решение);
  • элемент <nav> расположенный после <header> (решение).