Чем queryselector отличается от getelementsbyclassname
Перейти к содержимому

Чем queryselector отличается от getelementsbyclassname

  • автор:

Разница между document.querySelectorAll() и document.body.getElementByClassName()

И document.querySelectorAll(«selector») и document.body.getElementsByClassName(«selector») возвращают массив найденных элементов по заданному селектору. Какая между ними разница тогда?

Отслеживать
124k 24 24 золотых знака 131 131 серебряный знак 312 312 бронзовых знаков
задан 16 мар 2016 в 12:11
user205358 user205358

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Например вот такая вот:

document.querySelectorAll(".div a") // все ссылки в блоке с классом div document.getElementsByClassName(".div a") // не найдет ничего 

Суть в том, что querySelectorAll понимает валидные css-селекторы ( от сюда и название ), поэтому можете исхитряться, как только умеете

document.querySelectorAll("ul li:first") // первый li в списке document.querySelectorAll("#id") // поиск по id document.querySelectorAll("input[name=login]") // и такое умеет 

UPD
В комментарии добавили, что тип возвращаемого массива отличается:

document.querySelectorAll() // NodeList document.getElementsByClass() // HTMLCollection 

Поиск: 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 :

 
Long article

Живые коллекции

Все методы «getElementsBy*» возвращают живую коллекцию. Такие коллекции всегда отражают текущее состояние документа и автоматически обновляются при его изменении.

В приведённом ниже примере есть два скрипта.

  1. Первый создаёт ссылку на коллекцию . На этот момент её длина равна 1 .
  2. Второй скрипт запускается после того, как браузер встречает ещё один , теперь её длина – 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

Вот документ с таблицей и формой.

  1. Таблицу с id=»age-table» .
  2. Все элементы label внутри этой таблицы (их три).
  3. Первый td в этой таблице (со словом «Age»).
  4. Форму form с именем name=»search» .
  5. Первый input в этой форме.
  6. Последний 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] // взять последний

Разница между «querySelector» и «getElementsBy»

В современном стандарте (ES 5) стало возможным использовать методы querySelector() и querySelectorAll() , которые ищут элементы по правилам CSS.

document.querySelectorAll(".block"); // выборка по классам document.querySelectorAll("article"); // выборка тегов document.querySelectorAll("ul a"); // выборка ссылок в теге

Метод querySelector() выбирает только первый найденный элемент, а метод querySelectorAll() выбирает все указанные элементы.

Методы, такие как getElementsByTagName() , getElementsByClassName() и другие, выбирает только определённый тип элементов (например только по тегам или классам), но их не рекомендуется использовать, т.к. они не сохраняют результат выборки.

var articles1 = document.getElementsByTagName('article'); var articles2 = document.querySelectorAll('article'); articles1; // [article] articles2; // [article] // тег удалён articles1; // [] articles2; // [article] 

При этом метод getElementById() сохраняет результат выборки в переменной, если сам элемент будет удалён на странице.

var article = document.getElementById("article"); article; // [article] // тег удалён article; // [article] (элемент в переменной не удаляется) 

Обновлено: 28 декабря 2023

  • Разница между «querySelector» и «getElementsBy»
  • Выборка пользовательского атрибута
  • Выборка родительского и соседних элементов

Выбор элементов с двумя классами: метод getElementsByClassName()

Для поиска элементов, сразу имеющих несколько классов в JavaScript, можно применить getElementsByClassName() и передать строчку с классами, разделенными пробелами:

Скопировать код

// Найдены элементы, которые имеют и class1, и class2 var simultaneousClassElements = document.getElementsByClassName('class1 class2');

Следует соблюдать точное соответствие порядка и регистра классов, заданных в HTML, иначе метод не обнаружит элементы.

Альтернативным вариантом является document.querySelectorAll() , который более толерантен к порядку классов и найдет элементы, содержащие хотя бы один из указанных классов:

Скопировать код

// Элементы с class1 или class2 теперь найдены var oneTwoClassElements = document.querySelectorAll('.class1, .class2');

Лучшее решение: мощь селекторов запросов

Отличие классов: логика Либо, Или

document.querySelectorAll(‘.class1, .class2’) отличается от getElementsByClassName() тем, что выбирает элементы, включающие хотя бы один из указанных классов.

Преобразование NodeList в массив для расширенного функционала

querySelectorAll() возвращает NodeList, который можно легко преобразовать в массив:

Скопировать код

// Преобразуем NodeList в массив для более гибкой работы var elementsArray = Array.from(document.querySelectorAll('.class1, .class2'));

Таким образом, становятся доступны методы массива, такие как forEach , map и filter .

Поддержка старых браузеров: регулярные выражения и циклы

Если возникает необходимость поддерживать устаревшие браузеры, где querySelectorAll() отсутствует, можно использовать обычные циклы и регулярные выражения для выбора элементов определенного класса.

Простота — залог успеха: используйте нативный JavaScript

Хотя библиотеки обладают большим набором функций, для выбора элементов по классам часто достаточно использовать нативный JavaScript. Библиотеки лучше применять для более сложных задач.

Визуализация

Представьте себе ситуацию, что на сцене выступают актеры в различных костюмах:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *