nodeList.forEachを使用してJavaScriptの同一処理をスマートに書く

## はじめに

※ JavaScriptが書ける人には不要な記事です。

ウェブサイトにおいてスライダーやモーダル、その他タブ等を実装するとき、そのページ上に複数存在する場合の記述方法の解説です。

今回はひとつのページ内で、スライダー（Swiper）を複数設置するシチュエーションがあったとします。

## ググるとよく出てくるやり方

まったく同じスライダーがページ内に3個あったとします。ググるとよく出てくる情報が以下のようなやり方です。

```html
<div class="js-swiper-1"></div>
<div class="js-swiper-2"></div>
<div class="js-swiper-3"></div>
```

```javascript
const swiper1 = new Swiper('.js-swiper-1', {});
const swiper2 = new Swiper('.js-swiper-2', {});
const swiper3 = new Swiper('.js-swiper-3', {});
```

スライダーが100個あったら100個同じことを書くのでしょうか？いえ、無理です・・・。


## NodeList.forEach を使用する方法

結論から書きます。

```html
<div class="js-swiper"></div>
<div class="js-swiper"></div>
<div class="js-swiper"></div>
```

```javascript
const sliders = document.querySelectorAll('.js-swiper');

sliders.forEach((slider) => {
  const swiper = new Swiper(slider, {});
});
```

## 解説

今回のものを実装するのに必要な知識は以下です。

* [Document.querySelectorAll()](https://developer.mozilla.org/ja/docs/Web/API/Document/querySelectorAll)
* [NodeList](https://developer.mozilla.org/ja/docs/Web/API/NodeList)
* [NodeList.prototype.forEach](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach)

### STEP1: Document.querySelectorAll() でNodeListを作る

まずは対象の要素を`Document.querySelectorAll()`を使用してNodeListを作成します。

```javascript
const sliders = document.querySelectorAll('.js-swiper');
```

これにより、変数`sliders`には[NodeList](https://developer.mozilla.org/ja/docs/Web/API/NodeList)が入ります。

### STEP2: NodeList.forEach()をまわす

[NodeList](https://developer.mozilla.org/ja/docs/Web/API/NodeList)には`NodeList.forEach()`というメソッドがあります。
要はNodeListに入っている要素の数だけ順番に処理が走ると言うことです。

そして、`NodeList.forEach()`のコールバック関数内で、各スライダーの処理を走らせます。

```javascript
sliders.forEach((slider) => {});

// アロー関数ではなく従来の関数で書くと...
sliders.forEach(function(slider) {});
```

### STEP3: コールバック関数内に処理を書く

コールバック関数内で、スライダーの処理を定義します。

```javascript
sliders.forEach((slider) => {
  const swiper = new Swiper(slider, {});
});
```

### DONE

これでスライダーの数が何個あったとしても、記述を追加する必要はありません。
もちろんコールバック関数の中身は自由に書けるので、例えば対象がアコーディオンだったとしても問題無く実装できます。

#### アコーディオンの実装例

```html
<dl class="faq">
  <div class="faq__item js-accordion">
    <dt class="faq__question js-accordion-toggle"></dt>
    <dd class="faq__answer js-accordion-content"></dd>
  </div>
  <div class="faq__item js-accordion">
    <dt class="faq__question js-accordion-toggle"></dt>
    <dd class="faq__answer js-accordion-content is-hidden"></dd>
  </div>
  <div class="faq__item js-accordion">
    <dt class="faq__question js-accordion-toggle"></dt>
    <dd class="faq__answer js-accordion-content is-hidden"></dd>
  </div>
</dl>
```

```javascript
const accordions = document.querySelectorAll('.js-accordion');

accordions.forEach((accordion) => {
  const button = accordion.querySelector('.js-accordion-toggle');
  const content = accordion.querySelector('.js-accordion-content');

  button.addEventListener('click', () => {
    content.classList.toggle('is-hidden');
  });
});
```

### 注意

本例でのJavaScriptはIE11では動作しないので、別途対応が必要です。

* [アロー関数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
* [Nodelist.prototype.forEach()](https://developer.mozilla.org/ja/docs/Web/API/NodeList)