Поиск: 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] // взять последний
Как найти элемент на странице сайта
Объект document предоставляет ряд методов для поиска и управления элементами на веб-страницые:
- getElementById(value) : выбирает элемент, у которого атрибут id равен value . Если элемента с таким идентификатором нет, то возвращается null
- getElementsByTagName(value) : выбирает все элементы, у которых тег равен value. Возвращает список элементов (список типа NodeList ), который аналогичен массиву.
- getElementsByClassName(value) : выбирает все элементы, которые имеют класс value. Возвращает список NodeList
- getElementsByName(value) : выбирает все элементы, которые называются value. Возвращает список NodeList
- querySelector(value) : выбирает первый элемент, который соответствует css-селектору value
- querySelectorAll(value) : выбирает все элементы, которые соответствуют css-селектору value. Возвращает список NodeList
Получение элементов по id
Например, найдем элемент по id:
METANIT.COM Home Page
С помощью вызова document.getElementById(«header») находим элемент, у которого . А с помощью свойства innerText можно получить текст найденного элемента.
Стоит отметить, что если элемент не найден, то метод возвращает null . Поэтому перед использованием элемента рекомендуется проверять его на null.
Поиск по определенному тегу
Поиск по определенному тегу:
METANIT.COM Home Page
Первый абзац
Второй абзац
С помощью вызова document.getElementsByTagName(«p») находим все элементы параграфов. Этот вызов возвращает список типа NodeList , который во многом аналогичен массиву и который содержит найденные элементы. Чтобы получить отдельные элементы этого списка, можно пробежаться по этому списку в цикле.
Первый абзац Второй абзац
Если нам надо получить только первый элемент, то можно к первому элементу найденной коллекции объектов:
const p = document.getElementsByTagName("p")[0]; console.log(p.innerText);
Если элементов с указанным тегом нет на странице, то возвращается пустой список. С помощью свойства length (как и в случае массивов) можно проверить количество найденных элементов:
const paragraphs = document.getElementsByTagName("p"); console.log(paragraphs.length);
Для перебора списка естественно можно использовать и другие виды циклов:
const paragraphs = document.getElementsByTagName(«p»); for (let i=0; i
Получение элементов по классу
Получение элементов по классу:
METANIT.COM Home Page
Page Text
Email: supercorp@zmail.com
Phone: +1-234-567-8901
const contacts = document.getElementsByClassName("contacts"); for (contact of contacts)
В данном случае выбираем все элементы с классом «contacts». Консольный вывод:
Email: supercorp@zmail.com Phone: +1-234-567-8901
Поиск элементов по атрибуту name
Метод getElementsByName() позволяет получить список из элементов по имени — атрибуту name . Данный метод применяется к элементам форм. Например:
METANIT.COM Language:
В данном случае выбираем все элементы, у которых атрибут name равен «lang». В примере выше это радиокнопки. Затем на консоль выводим значение атрибута value каждого полученного элемента. Консольный вывод:
Java JavaScript PHP
Стоит отметить, что этот метод может работать несколько иначе в старых браузерах типа Internet Explorer или Opera. В частности, он выбирает элемент, если не только его атрибут name соответствует переданному значению, но и атрибут id.
Поиск элементов по селектору CSS
Выбор по селектору CSS:
METANIT.COM Аннотация статьи
Первый абзац
Второй абзац
Выражение document.querySelector(«.annotation p») находит элемент, который соответствует селектору .annotation p . Если на странице несколько элементов, соответствующих селектору, то метод выберет первый из них.
Чтобы получить все элементы по селектору, можно подобным образом использовать метод document.querySelectorAll , который возвращает список NodeList из найденных элементов:
METANIT.COM Аннотация статьи
const elems = document.querySelectorAll(".text p"); for (elem of elems)Первый абзац
Второй абзац
Первый абзац Второй абзац
Поиск во вложенных элементах
Подобным образом мы можем искать элементы не только во всем документе, но и в отдельных элементах на веб-странице. Например:
METANIT.COM Home Page
Page Text 1
Page Text 2
// получаем элемент с const article = document.getElementById("article"); // в этом элементе получаем все элементы с const articleContent = article.getElementsByClassName("text"); for(p of articleContent)Footer Text
В данном случае мы сначала получаем элемент с , затем внутри этого элемента ищем все элементы с . В результате консоль выведет два элемента:
Page Text 1
Page Text 2
Селекторы CSS
Перечислю вкратце список базовых CSS-селекторов, которые мы можем применять для поиска элементов:
- * : выбирает все элементы
- E : выбирает все элементы типа E
- [a] : выбирает все элементы с атрибутом a
- [a=»b»] : выбирает все элементы, в которых атрибут a имеет значение b
- [a~=»b»] : выбирает все элементы, в которых атрибут a имеет список значений, и одно из этих значений равно b
- [a^=»b»] : выбирает все элементы, в которых значение атрибута a начинается на b
- [a$=»b»] : выбирает все элементы, в которых значение атрибута a завершается на b
- [a*=»b»] : выбирает все элементы, в которых значение атрибута a содержит подстроку b
- [a|=»b»] : выбирает все элементы, в которых значение атрибута a представляет ряд значений, разделенных дефисами, и первое из этих значений равно b
- :root : выбирает корневой элемент документа
- :nth-child(n) : выбирает n-ый вложенный элемент (отсчет идет с начала)
- :nth-last-child(n) : выбирает n-ый вложенный элемент (отсчет идет с конца)
- :nth-of-type(n) : выбирает n-ый сестринский элемент типа type (отсчет идет с начала)
- :nth-last-of-type(n) : выбирает n-ый сестринский элемент типа type (отсчет идет с конца)
- :first-child : выбирает первый вложенный элемент
- :last-child : выбирает последний вложенный элемент
- :first-of-type : выбирает первый сестринский элемент типа type
- :last-of-type : выбирает последний сестринский элемент типа type
- :only-child : выбирает все элементы, которые имеют только один вложенный элемент
- :only-of-type : выбирает все сестринские элементы типа type
- :empty : выбирает все элементы, которые не имеют вложенных элементов
- :link : выбирает все ссылки, которые еще не были нажаты
- :visited : выбирает все ссылки, которые уже были нажаты
- :active : выбирает все ссылки, которые в текущий момент активны (нажимаются)
- :hover : выбирает все ссылки, над которыми в текущий момент находится курсор
- :focus : выбирает все элементы, которые в текущий момент получили фокус
- :target : выбирает все элементы, к которым можно обратиться с помощью адресов url внутри страницы
- :lang(en) : выбирает все элементы, в которых атрибут lang имеет значение «en»
- :enabled : выбирает все элементы форм, которые доступны для взаимодействия
- :disabled : выбирает все элементы форм, которые НЕ доступны для взаимодействия
- :checked : выбирает все флажки (чекбоксы) и радиокнопки, которые отмечены
- .class : выбирает все элементы с классом class
- #id : выбирает все элементы с идентификтором id
- :not(s) : выбирает все элементы, которые не соответствуют селектору s
- E F : выбирает все элементы типа F, которые встречаются в элементах типа E
- E > F : выбирает все элементы типа F, которые являются вложенными в элементы типа E
- E + F : выбирает все элементы типа F, которые располагаются сразу после элементов типа E
- E ~ F : ввыбирает все элементы типа F, которые являются сестринскими по отношению к элементам типа E
Дополнительные замечания
Стоит отметить, что из всех этих способов выбор по id обычно самый быстрый. При всех прочих условиях лучше выбирать метод getElementById()
Также для оптимизации работы с DOM для того, чтобы избежать повторной выборки одних и тех же элементов, при первой выборке их лучше сохранять в константы/переменные.
Ряд методов — getElementsByTagName() , getElementsByClassName() , getElementsByName() , querySelectorAll() возвращает список элементов в виде объекта NodeList , который аналогичен массиву и который мы можем перебрать и получить каждый отдельный элемент из этого набора. Однако метод querySelectorAll() возвращает статический список NodeList, тогда как остальные методы возвращают нестатический список. В чем разница? При изменении элементов нестатического списка все изменения сразу же применяются к веб-странице. При изменении элементов из статического списка изменения могут не сразу изменяться.
Как найти CSS селектор нужного элемента на странице товара.
С помощью CSS селекторов можно найти путь, по которому находится нужный элемент.
Мы разберем пример как можно подобрать нужный вам селектор с использованием возможностей браузера Chrome. Откроем в браузере страницу необходимого нам товара, например в маркете. Мы знаем что для использования нашего расширения нам необходимо выделить 3 атрибута товара
Далее мы будем подбирать селекторы именно для этих элементов.
Кликнем правой кнопкой мыши на название товара и выберем пункт меню “Посмотреть код”.

Откроется встроенный в браузер инструмент ChromeDevTools, который отразит во вкладке “Elements” весь html код страницы. При этом будет подсвечен тот тэг, который относится к выбранному вами элементу.

Разберемся что такое тэг — это элемент который представляет ассоциированное ключевое слово, он может быть как одиночным (
— перенос на другую строку), так и парным: открывающим (
) и закрывающим (
). Парные тэги заключают между собой информацию которая видна на странице. Также тэг может быть снабжен одним или несколькими атрибутами. Атрибут состоит из названия и значения.

Дальше мы кликаем правой кнопкой мыши по выделенному тэгу. В выпадающем меню выбираем “Copy” и далее “Copy selector”. Селектор находится у нас в буфере обмена, далее мы можем поместить данный селектор в окно нашего расширения.

Важна уникальность CSS селектора, так как в противном случае сбор данных будет не точным и бесполезным. Проверить уникальный код можно прямо через вкладку “Elements”: нажмите сочетание клавиш Ctrl + F и укажите скопированный вами селектор в поисковой строке вкладки “Elements”, и количество подобных селекторов на странице отобразится в правом углу поисковой строки.

Точно таким же способом найдем CSS селектор изображения товара, но возьмем для примера другой интернет магазин. Здесь в карточке товара есть элемент карусель и по умолчанию первым изображением является видео товара. Нам необходимо для начала выбрать изображение и кликнув правой кнопкой мыши выбрать “Посмотреть код”.

Снова видим во вкладке “Elements” выделенный тэг, который относится к данному изображению. Кликаем правой кнопкой мыши, выбираем “Copy” и далее “Copy selector”.

Аналогично поступаем с ценой. В нашем примере есть 2 цены: одна со скидкой и одна без. Кликаем нужную нам цену правой кнопкой мыши, и далее выше описанным способом копируем селектор данной цены.
Скопированные селекторы вы помещаете в окне нашего расширения, снабдив их соответствующими атрибутами:
“image”:”*тут размещаете селектор изображения товара*”;
“price”:”*тут размещаете селектор цены товара*”>
например:
«title»: «body > div._111XI.main > div:nth-child(5) > div > div:nth-child(5) > div > div._3faMG._1k7g2._2p5aS > div.ULRXT.cia-cs > div._3faMG._3YZTV > div > div:nth-child(3) > div > div > h3»,
«image»: «body > div._111XI.main > div:nth-child(5) > div > div:nth-child(5) > div > div._3faMG._1k7g2._2p5aS > div.ULRXT.cia-cs > div._3faMG._3YZTV > div > div:nth-child(6) > div > div > div > a > img»,
«price»: «body > div._111XI.main > div:nth-child(5) > div > div:nth-child(5) > div > div:nth-child(2) > section > div:nth-child(2) > div > div > div > div > div:nth-child(2) > div.KnVez > div > div > span > span:nth-child(1)»
>
Теперь перенесем все в окно продвинутого выделения нашего расширения.
Как найти элемент в коде
Новичку очень трудно найти нужный символ или слово в массе кода, однако это делается очень быстро и просто. Если не знаете как, то читайте дальше.
В следующей статье, мы приступим к редактированию шаблона, и нам придётся находить нужные элементы в коде темы.
Если кто-то ещё не видел, что из себя представляет код шаблона, то зайдите в Консоль — Внешний вид — Редактор.
Перед Вами откроется код файла style.css . Покрутите его вниз, и первое, что придёт Вам в голову будет: ё-моё, как же в этой массе английских слов, цифр и символов, найти то, что нам будет нужно.
Для полноты ощущения, можно открыть один из php файлов, которые расположены в колонке справа от поля редактора.
Только сразу отгоните мысль типа: «Я в этом до самой смерти не разберусь». Разберётесь, и я Вам в этом помогу.
Рассмотрим два варианта, в зависимости от начальных условий, нахождения нужного элемента в коде.
Условие: мы точно знаем то, что нам нужно найти.
Для примера возьмём код страницы.
Комбинация клавиш Contrl-F откроет окно поиска в правом верхнем углу, в которое можно ввести искомый элемент кода. Элемент и все его повторения подсветятся.

Этот поиск работает абсолютно для любого кода, открытого в браузере, то есть на странице.
Условие: мы видим элемент на странице, но не знаем ни его html, ни css.
В этом случае потребуется web-инспектор, или по другому Инструмент разработчика.
Инструмент разработчика есть во всех браузерах и открыть его можно или клавишей F12, или правой клавишей мыши, выбрав «Просмотреть код» или «Исследовать элемент». В разных браузерах по разному.
Главное не выбирайте «Просмотреть код страницы». Похоже, но не то.
После этого появится web-инспектор. Его интерфейс в разных браузерах немного отличается, но принцип действия везде одинаковый.
Я покажу на примере web-инспектора Chrome.
Заходим на страницу и открываем web-инспектор. По умолчанию он откроется в двух колонках, в левой будет html код всех элементов, находящихся на странице, а в правой — css оформление.

Изначально, код откроется в сложенном виде, то есть будут видны только основные элементы страницы, но если щёлкнуть по треугольничку в начале строки, то откроются все вложения, находящиеся в элементе.
И вот так, открывая вложение за вложением, можно добраться практически до любого элемента, находящегося на странице.
Определить, какой код, какому элементу соответствует, очень просто.
Надо просто вести по строкам курсором, и как только курсор оказывается на строке с кодом, так тут-же элемент, которому соответствует этот код, подсвечивается.

Теперь найдём css этого элемента. Для этого надо один раз щёлкнуть левой клавишей по строке с html, и в правой колонке отобразятся все стили, которые ему заданы, а так-же стили, влияющие на элемент, от родительских элементов.

Теперь, зная class или id элемента, можно спокойно идти в файл style.css, найти в нём нужный селектор, с помощью Поиска (Ctrl+F), и править внешний вид элемента.
Желаю творческих успехов.
Неужели не осталось вопросов? Спросить

Перемена
— Мам, ну почему ты думаешь, что если я была на дне рождения, то сразу пила?!
— Дочь а нечего что я папа?
Объявление в метро: «при обнаружении подозрительных предметов сделайте подозрительное лицо.