Перебор: each и map
Большинство методов jQuery сами применяются ко всем элементам. Но иногда для каждого элемента нужно сделать что-то своё: прочитать его данные, посчитать, сравнить. Для этого есть перебор методом each().
Метод each
<ul id="tasks">
<li>Купить хлеб</li>
<li class="done">Позвонить Олегу</li>
<li>Написать отчёт</li>
</ul>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
$('#tasks li').each(function (index, element) {
const $item = $(element);
const mark = $item.hasClass('done') ? '[x]' : '[ ]';
console.log(mark, $item.text());
});
</script>Функция вызывается для каждого пункта. Она получает индекс и обычный элемент DOM, поэтому его оборачивают в $, чтобы вызвать методы jQuery. В выводе три строки с отметками.
this внутри each
В функции, объявленной через function, слово this указывает на текущий элемент. В старом коде пишут именно так:
<ul>
<li>Купить хлеб</li>
<li>Позвонить Олегу</li>
</ul>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
$('li').each(function () {
console.log($(this).text().length);
});
</script>В стрелочной функции своего this нет, поэтому с ней пользуйтесь вторым аргументом element.
Досрочный выход
Чтобы прервать перебор, функция возвращает false:
<ul>
<li>Купить хлеб</li>
<li class="done">Позвонить Олегу</li>
<li class="done">Написать отчёт</li>
</ul>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
$('li').each(function (index) {
if ($(this).hasClass('done')) {
console.log('Первая выполненная задача — номер', index + 1); // 2
return false;
}
});
</script>Перебор остановился на втором пункте, третий не проверялся.
Метод map
map() собирает из набора новые значения. Результат — объект jQuery, а обычный массив из него получают методом get():
<ul>
<li>Купить хлеб</li>
<li>Позвонить Олегу</li>
</ul>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
const titles = $('li').map(function () {
return $(this).text();
}).get();
console.log(titles.join(', ')); // Купить хлеб, Позвонить Олегу
</script>Функции $.each и $.map
У jQuery есть и функции с теми же именами для обычных массивов и объектов. Порядок аргументов у них разный:
| Вызов | Аргументы функции |
|---|---|
$('li').each(fn) | индекс, элемент |
$('li').map(fn) | индекс, элемент |
$.each(array, fn) | индекс, значение |
$.map(array, fn) | значение, индекс |
Подробнее о $.each — в уроке о служебных функциях. Для массивов сегодня удобнее встроенные forEach() и map().
То же на обычном JavaScript
<ul>
<li>Купить хлеб</li>
<li>Позвонить Олегу</li>
</ul>
<script>
const titles = Array.from(document.querySelectorAll('li'), (li) => li.textContent);
console.log(titles.join(', '));
</script>Частая ошибка
Забыть get() после map(). Без него получится объект jQuery, а не массив: titles.join вызовет ошибку titles.join is not a function.