How do you get all elements by class name using pure JavaScript? Analogous to $('.class')
in JQuery
?
D M
5,5414 gold badges12 silver badges27 bronze badges
asked Feb 24, 2012 at 8:00
1
document.getElementsByClassName(klass)
Be aware that some engines (particularly the older browsers) don’t have it. You might consider using a shim, if that’s the case. It will be slow, and iterate over the whole document, but it will work.
EDIT several years later: You can get the same result using document.querySelectorAll('.klass')
, which doesn’t seem like much, but the latter allows queries on any CSS selector, which makes it much more flexible, in case “get all elements by class name” is just a step in what you are really trying to do, and is the vanilla JS answer to jQuery’s $('.class')
.
answered Feb 24, 2012 at 8:02
AmadanAmadan
189k23 gold badges236 silver badges298 bronze badges
0
A Simple and an easy way
var cusid_ele = document.getElementsByClassName('custid');
for (var i = 0; i < cusid_ele.length; ++i) {
var item = cusid_ele[i];
item.innerHTML = 'this is value';
}
answered Mar 22, 2013 at 0:38
ktakta
19.2k7 gold badges65 silver badges47 bronze badges
1
document.getElementsByClassName('your class');
or you can build your classname like this, if that doesn’t work try this
if (!document.getElementsByClassName) {
document.getElementsByClassName=function(cn) {
var allT=document.getElementsByTagName('*'), allCN=[], i=0, a;
while(a=allT[i++]) {
a.className==cn ? allCN[allCN.length]=a : null;
}
return allCN
}
}
answered Feb 24, 2012 at 8:03
Kunal VashistKunal Vashist
2,3806 gold badges29 silver badges58 bronze badges
In some browsers there is a document.getElementsByClassName(class)
function. Otherwise, the only option you have is to iterate over all elements in the document by checking each of it against your condition of having the required class name.
answered Feb 24, 2012 at 8:03
penarturpenartur
9,7545 gold badges38 silver badges50 bronze badges
answered Feb 24, 2012 at 8:08
graphicdivinegraphicdivine
10.8k7 gold badges32 silver badges58 bronze badges
function getElementsByClassName(oElm, strTagName, strClassName){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all :
oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
strClassName = strClassName.replace(/-/g, "\-");
var oRegExp = new RegExp("(^|\s)" + strClassName + "(\s|$)");
var oElement;
for(var i=0; i<arrElements.length; i++){
oElement = arrElements[i];
if(oRegExp.test(oElement.className)){
arrReturnElements.push(oElement);
}
}
return (arrReturnElements)
}
answered Feb 24, 2012 at 8:06
Sudhir BastakotiSudhir Bastakoti
98.7k15 gold badges156 silver badges162 bronze badges
1
This should work:
function(className)
{
var matchingItems = [];
var allElements = document.getElementsByTagName("*");
for(var i=0; i < allElements.length; i++)
{
if(allElements [i].className == className)
{
matchingItems.push(allElements[i]);
}
}
return matchingItems;
}
answered Feb 24, 2012 at 8:05
spinonspinon
10.7k5 gold badges41 silver badges58 bronze badges
3
I’d like to modify all classes with JS.
Is there way to select them without manually setting the array index (for example [0] or [1] or [184])?
Example code:
<div class='message'>something:</div>
<div class='message'>something</div>
const element = document.querySelectorAll(".message");
element.classList.add("color");
It works only when I add [0]
and only for the first element that has the class.
But I’d like to modify all the elements with the class.
asked Mar 23, 2019 at 15:26
OliverOliver
3112 gold badges4 silver badges21 bronze badges
2
It’s important to learn what basic language syntax does first. The [0]
is selecting the 0
index of an array (or array-like object). So to operate on them all, you can use a loop with a variable that is incremented starting at 0
and continuing until it goes out of bounds of the array.
function replaceEmotes() {
var messages = document.querySelectorAll(".message");
for (var i = 0; i < messages.length; i++) {
var str = messages[i].innerHTML.replace(":smile:", "<i class='em em-smile'></i>");
messages[i].innerHTML = str;
}
}
There are other ways too, but this is a fundamental syntax that should probably be learned first.
answered Mar 23, 2019 at 15:29
ziggy wiggyziggy wiggy
1,0396 silver badges6 bronze badges
2
Use forEach to iterate over all message nodes and replace emotes. Also note that I’m using a global regexp to replace all :smile:
strings within a message, not just the first one.
function replaceEmotes() {
var messages = document.querySelectorAll(".message");
messages.forEach(message => {
message.innerHTML = message.innerHTML.replace(/:smile:/g, "<i class='em em-smile'></i>");
});
}
answered Mar 23, 2019 at 15:36
abadalyanabadalyan
1,2058 silver badges13 bronze badges
document.querySelectorAll()
selects all elements of given class name and store them in an array-like object. It is possible to loop through the objects instead of accessing them manually.
var elements = document.querySelectorAll('.className');
for(var i = 0; i < elements.length; i++){
var str = elements[i].innerHTML;
elements[i].innerHTML = str.replace(":smile:", "<i class='em em-smile'></i>");
}
You can also do the same thing using document.getElementsByClassName()
var elements = document.getElementsByClassName('className');
for(var i = 0; i < elements.length; i++){
// Same like above...
}
Mads Hansen
62.9k12 gold badges111 silver badges144 bronze badges
answered Mar 23, 2019 at 15:41
Adnan TokyAdnan Toky
1,7122 gold badges11 silver badges19 bronze badges
you can use document.getElementsByClassName("message")
and loop through all the elements in the NodeList
answered Mar 23, 2019 at 15:31
Поиск элементов
Чтобы скрипт мог работать с каким-то элементом страницы, нужно сначала найти этот элемент.
Для этого в JavaScript есть несколько способов. Найденный элемент
обычно записывается в переменную.
Через эту переменную сркипт обращается к элементу и производит с ним какие-то действия.
Поиск по id
Если элементу задан атрибут id, то элемент можно найти по id. Это
самый простой способ. Поиск элемента производится с помощью метода
getElementById() глобального объекта document.
document.getElementById (id)
Параметры:
id – id элемента, который нужно найти. id – это строка, поэтому она
должна быть в кавычках.
Создадим страницу, добавим на неё элемент и зададим ему id. В
скрипте найдём этот элемент:
HTML код:
+
8 |
<div id="block">Блок с id</div> |
JavaScript:
10 |
let block = document.getElementById('block'); console.log(block); |
Найденный элемент мы присвоили переменной block и вывели переменную в консоль. Откройте консоль браузера,
в ней должен быть указан элемент.
Так как посик по id – это самый простой и удобный способ, часто используют именно его. Если с каким-то
элементом нужно работать в скрипте, то в коде страницы этому элементу устанавливают атрибут
id, даже если он не был установлен ранее. И находят элемент по id.
Поиск по классу
Метод getElementsByClassName() позволяет найти все элементы, относящиеся к
определённому классу.
document.getElementsByClassName (класс)
Параметры:
класс – класс элементов, которые нужно найти
Метод возвращает псевдомассив, содержащий найденные элементы. Псевдомассивом он называется потому, что
для него не работают многие методы массивов. Но главное свойство остаётся – можно обратиться к любому
элементу массива. Даже если найден только один элемент, он всё равно находится в массиве.
Добавим на страницу элементы и зададим им класс. Часть элементов разместим внутри блока, который мы
создали ранее. Другую часть создадим вне блока. Смысл этого будет понятен чуть позднее. Теперь страница
будет выглядеть так:
HTML код:
8 |
<div id="block">Блок с id <p class="art">Абзац в блоке</p> <p class="art">Ещё один абзац в блоке</p> </div> <p class="art">Отдельный абзац</p> |
JavaScript:
16 |
let art = document.getElementsByClassName('art'); console.log(art); console.log(art[0]); |
В строке 17 мы вывели в консоль весь массив, чтобы посмотреть, сколько в нём элементов, а в строке 18
мы обратились к конкретному элементу.
Любой метод, рассматриваемый в данной теме, можно применить не только ко всему документу,
но и к конкретному элементу. Например, к блоку, который есть на нашей странице. При этом будут найдены
не все элементы, а только те, которые находятся внутри блока. Найдём элементы класса
art, находящиеся в блоке:
19 |
let artIn = block.getElementsByClassName('art'); console.log(artIn); |
Теперь найдены только те элементы, которые расположены в блоке.
Поиск по тэгу
Метод getElementsByTagName() находит все элементы с конкретным тэгом.
Он также возвращает псевдомассив с найденными элементами.
document.getElementsByTagName (тэг)
Параметры:
тэг – тэг элементов, которые нужно найти
Найдём все тэги p, которые есть на странице:
21 |
let p = document.getElementsByTagName('p'); console.log(p); |
Этот метод можно также применять не ко всему документу, а к конкретному элементу. Найдите все тэги
p, находящиеся в блоке.
Поиск по селектору
Методы querySelector() и
querySelectorAll() находят
элементы, соответсвующие определённому
селектору.
Метод querySelectorAll() находит все элементы, соответствующие
селектору. А метод querySelector() находит только
первый элемент. Эти методы могут заменить все способы поиска
элементов, рассмотренные ранее.
Ведь есть селектор по id, селектор по тэгу и многие другие.
document.querySelector (селектор)
document.querySelectorAll (селектор)
Селекторы пишутся точно так же, как в CSS, только не забывайте ставить кавычки.
Добавим на страницу список и найдём его по селектору. Мы ищем только один элемент и мы точно знаем, что
он будет первый, потому что он один на странице. Поэтому в данном случае удобнее использовать метод
querySelector(). Но при использовании этого метода нужно учитывать, что в
дальнейшем на страницу могут быть добавлены такие же элементы. Впрочем, это касается большинства методов.
HTML код:
13 |
<ul> <li>Первый пункт</li> <li>Второй пункт</li> </ul> |
JavaScript:
27 |
let element = document.querySelector('ul'); console.log(element); |
Теперь найдём не сам список, а его пункты. Для поиска элементов можно использовать любые селекторы.
Мы используем составной селектор:
29 |
let li = document.querySelectorAll('ul li'); console.log(li); |
Данные методы также могут производить поиск не во всём документе, а внутри конеретного элемента.
В примере мы использовали только селекторы по тэгу. Попробуйте найти элементы страницы с использованием
других селекторов.
Соседние элементы
Для найденного элемента можно найти соседей. Каждый элемент является объектом, и соседние элементы можно
получить через свойства этого объекта. Свойство previousElementSibling
содержит предыдущий элемент, а свойство
nextElementSibling содержит следующий элемент.
элемент.previousElementSibling
элемент.nextElementSibling
Найдём элемент, следующий за блоком:
31 |
let blockPre = block.nextElementSibling; console.log(blockPre); |
Свойства previousSibling и nextSibling
тоже содержат соседей, но они учитывают не только элементы, но и другие узлы.
Перед первым абзацем идёт текст
“Блок с id”. Найдём этот текстовый узел. Абзац содержится в нескольких псевдомассивах, созданных нами
в примерах, в том числе, в массиве art. Обратимся к нему через этот массив:
33 |
let text = art[0].previousSibling; console.log(text); |
Дочерние элементы
Свойство children содержит массив с дочерними элементами.
элемент.children
Найдём дочерние элементы блока:
35 |
let blockIn = block.children; console.log(blockIn); |
Свойство childNodes содержит не только элементы, но и другие узлы. Найдём
все узлы, которые находятся в блоке:
37 |
let blockAll = block.childNodes; console.log(blockAll); |
Поиск: getElement*, querySelector*
Свойства навигации по DOM хороши, когда элементы расположены рядом. А что, если нет? Как получить произвольный элемент страницы?
Для этого в DOM есть дополнительные методы поиска.
document.getElementById или просто id
Если у элемента есть атрибут id
, то мы можем получить его вызовом document.getElementById(id)
, где бы он ни находился.
Например:
<div id="elem"> <div id="elem-content">Element</div> </div> <script> // получить элемент *!* let elem = document.getElementById('elem'); */!* // сделать его фон красным elem.style.background = 'red'; </script>
Также есть глобальная переменная с именем, указанным в id
:
<div id="*!*elem*/!*"> <div id="*!*elem-content*/!*">Элемент</div> </div> <script> // elem - ссылка на элемент с id="elem" elem.style.background = 'red'; // внутри id="elem-content" есть дефис, так что такой id не может служить именем переменной // ...но мы можем обратиться к нему через квадратные скобки: window['elem-content'] </script>
…Но это только если мы не объявили в JavaScript переменную с таким же именем, иначе она будет иметь приоритет:
<div id="elem"></div> <script> let elem = 5; // теперь elem равен 5, а не <div id="elem"> alert(elem); // 5 </script>
Это поведение соответствует [стандарту](https://html.spec.whatwg.org/#dom-window-nameditem), но поддерживается в основном для совместимости, как осколок далёкого прошлого.
Браузер пытается помочь нам, смешивая пространства имён JS и DOM. Это удобно для простых скриптов, которые находятся прямо в HTML, но, вообще говоря, не очень хорошо. Возможны конфликты имён. Кроме того, при чтении JS-кода, не видя HTML, непонятно, откуда берётся переменная.
В этом учебнике мы будем обращаться к элементам по `id` в примерах для краткости, когда очевидно, откуда берётся элемент.
В реальной жизни лучше использовать `document.getElementById`.
“`smart header=”Значение id
должно быть уникальным”
Значение `id` должно быть уникальным. В документе может быть только один элемент с данным `id`.
Если в документе есть несколько элементов с одинаковым значением id
, то поведение методов поиска непредсказуемо. Браузер может вернуть любой из них случайным образом. Поэтому, пожалуйста, придерживайтесь правила сохранения уникальности id
.
```warn header="Только `document.getElementById`, а не `anyElem.getElementById`"
Метод `getElementById` можно вызвать только для объекта `document`. Он осуществляет поиск по `id` по всему документу.
querySelectorAll [#querySelectorAll]
Самый универсальный метод поиска – это elem.querySelectorAll(css)
, он возвращает все элементы внутри elem
, удовлетворяющие данному CSS-селектору.
Следующий запрос получает все элементы <li>
, которые являются последними потомками в <ul>
:
<ul> <li>Этот</li> <li>тест</li> </ul> <ul> <li>полностью</li> <li>пройден</li> </ul> <script> *!* let elements = document.querySelectorAll('ul > li:last-child'); */!* for (let elem of elements) { alert(elem.innerHTML); // "тест", "пройден" } </script>
Этот метод действительно мощный, потому что можно использовать любой CSS-селектор.
Псевдоклассы в CSS-селекторе, в частности `:hover` и `:active`, также поддерживаются. Например, `document.querySelectorAll(':hover')` вернёт коллекцию (в порядке вложенности: от внешнего к внутреннему) из текущих элементов под курсором мыши.
querySelector [#querySelector]
Метод elem.querySelector(css)
возвращает первый элемент, соответствующий данному CSS-селектору.
Иначе говоря, результат такой же, как при вызове elem.querySelectorAll(css)[0]
, но он сначала найдёт все элементы, а потом возьмёт первый, в то время как elem.querySelector
найдёт только первый и остановится. Это быстрее, кроме того, его короче писать.
matches
Предыдущие методы искали по DOM.
Метод elem.matches(css) ничего не ищет, а проверяет, удовлетворяет ли elem
CSS-селектору, и возвращает true
или false
.
Этот метод удобен, когда мы перебираем элементы (например, в массиве или в чём-то подобном) и пытаемся выбрать те из них, которые нас интересуют.
Например:
<a href="http://example.com/file.zip">...</a> <a href="http://ya.ru">...</a> <script> // может быть любая коллекция вместо document.body.children for (let elem of document.body.children) { *!* if (elem.matches('a[href$="zip"]')) { */!* alert("Ссылка на архив: " + elem.href ); } } </script>
closest
Предки элемента – родитель, родитель родителя, его родитель и так далее. Вместе они образуют цепочку иерархии от элемента до вершины.
Метод elem.closest(css)
ищет ближайшего предка, который соответствует CSS-селектору. Сам элемент также включается в поиск.
Другими словами, метод closest
поднимается вверх от элемента и проверяет каждого из родителей. Если он соответствует селектору, поиск прекращается. Метод возвращает либо предка, либо null
, если такой элемент не найден.
Например:
<h1>Содержание</h1> <div class="contents"> <ul class="book"> <li class="chapter">Глава 1</li> <li class="chapter">Глава 2</li> </ul> </div> <script> let chapter = document.querySelector('.chapter'); // LI alert(chapter.closest('.book')); // UL alert(chapter.closest('.contents')); // DIV alert(chapter.closest('h1')); // null (потому что h1 - не предок) </script>
getElementsBy*
Существуют также другие методы поиска элементов по тегу, классу и так далее.
На данный момент, они скорее исторические, так как querySelector
более чем эффективен.
Здесь мы рассмотрим их для полноты картины, также вы можете встретить их в старом коде.
elem.getElementsByTagName(tag)
ищет элементы с данным тегом и возвращает их коллекцию. Передав"*"
вместо тега, можно получить всех потомков.elem.getElementsByClassName(className)
возвращает элементы, которые имеют данный CSS-класс.document.getElementsByName(name)
возвращает элементы с заданным атрибутомname
. Очень редко используется.
Например:
// получить все элементы div в документе let divs = document.getElementsByTagName('div');
Давайте найдём все input
в таблице:
<table id="table"> <tr> <td>Ваш возраст:</td> <td> <label> <input type="radio" name="age" value="young" checked> младше 18 </label> <label> <input type="radio" name="age" value="mature"> от 18 до 50 </label> <label> <input type="radio" name="age" value="senior"> старше 60 </label> </td> </tr> </table> <script> *!* let inputs = table.getElementsByTagName('input'); */!* for (let input of inputs) { alert( input.value + ': ' + input.checked ); } </script>
“`warn header=”Не забываем про букву "s"
!”
Одна из самых частых ошибок начинающих разработчиков (впрочем, иногда и не только) – это забыть букву `”s”`. То есть пробовать вызывать метод `getElementByTagName` вместо getElementsByTagName
.
Буква "s"
отсутствует в названии метода getElementById
, так как в данном случае возвращает один элемент. Но getElementsByTagName
вернёт список элементов, поэтому "s"
обязательна.
````warn header="Возвращает коллекцию, а не элемент!"
Другая распространённая ошибка - написать:
```js
// не работает
document.getElementsByTagName('input').value = 5;
Попытка присвоить значение коллекции, а не элементам внутри неё, не сработает.
Нужно перебрать коллекцию в цикле или получить элемент по номеру и уже ему присваивать значение, например, так:
// работает (если есть input) document.getElementsByTagName('input')[0].value = 5;
Ищем элементы с классом `.article`:
```html run height=50
<form name="my-form">
<div class="article">Article</div>
<div class="long article">Long article</div>
</form>
<script>
// ищем по имени атрибута
let form = document.getElementsByName('my-form')[0];
// ищем по классу внутри form
let articles = form.getElementsByClassName('article');
alert(articles.length); // 2, находим два элемента с классом article
</script>
```
## Живые коллекции
Все методы `"getElementsBy*"` возвращают *живую* коллекцию. Такие коллекции всегда отражают текущее состояние документа и автоматически обновляются при его изменении.
В приведённом ниже примере есть два скрипта.
1. Первый создаёт ссылку на коллекцию `<div>`. На этот момент её длина равна `1`.
2. Второй скрипт запускается после того, как браузер встречает ещё один `<div>`, теперь её длина - `2`.
```html run
<div>First div</div>
<script>
let divs = document.getElementsByTagName('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
*!*
alert(divs.length); // 2
*/!*
</script>
```
Напротив, `querySelectorAll` возвращает *статическую* коллекцию. Это похоже на фиксированный массив элементов.
Если мы будем использовать его в примере выше, то оба скрипта вернут длину коллекции, равную `1`:
```html run
<div>First div</div>
<script>
let divs = document.querySelectorAll('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
*!*
alert(divs.length); // 1
*/!*
</script>
```
Теперь мы легко видим разницу. Длина статической коллекции не изменилась после появления нового `div` в документе.
## Итого
Есть 6 основных методов поиска элементов в DOM:
<table>
<thead>
<tr>
<td>Метод</td>
<td>Ищет по...</td>
<td>Ищет внутри элемента?</td>
<td>Возвращает живую коллекцию?</td>
</tr>
</thead>
<tbody>
<tr>
<td><code>querySelector</code></td>
<td>CSS-selector</td>
<td>✔</td>
<td>-</td>
</tr>
<tr>
<td><code>querySelectorAll</code></td>
<td>CSS-selector</td>
<td>✔</td>
<td>-</td>
</tr>
<tr>
<td><code>getElementById</code></td>
<td><code>id</code></td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td><code>getElementsByName</code></td>
<td><code>name</code></td>
<td>-</td>
<td>✔</td>
</tr>
<tr>
<td><code>getElementsByTagName</code></td>
<td>tag or <code>'*'</code></td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td><code>getElementsByClassName</code></td>
<td>class</td>
<td>✔</td>
<td>✔</td>
</tr>
</tbody>
</table>
Безусловно, наиболее часто используемыми в настоящее время являются методы `querySelector` и `querySelectorAll`, но и методы `getElement(s)By*` могут быть полезны в отдельных случаях, а также встречаются в старом коде.
Кроме того:
- Есть метод `elem.matches(css)`, который проверяет, удовлетворяет ли элемент CSS-селектору.
- Метод `elem.closest(css)` ищет ближайшего по иерархии предка, соответствующему данному CSS-селектору. Сам элемент также включён в поиск.
И, напоследок, давайте упомянем ещё один метод, который проверяет наличие отношений между предком и потомком:
- `elemA.contains(elemB)` вернёт `true`, если `elemB` находится внутри `elemA` (`elemB` потомок `elemA`) или когда `elemA==elemB`.