Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Перебор: 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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.