HTML・CSS

querySelectorAllしてforEachする入門【JavaScript】

2022/01/31

現在JavaScriptを学習中なのですが、最近覚えた「querySelectorAllで複数要素を取得して、forEachで全ての要素に処理をする」という合わせ技が非常に便利で感動しました。

初学者である私のような学習段階限定で便利になる技というわけではなく、querySelectorAllとforEachのメソッドを使う方法はモダンなJavaScriptにおいて頻繁に利用されている用法のようです。

そこで本記事ではquerySelectorAllとforEachの使い方を、実際に簡単なものを動かしつつ、例を交えて紹介させていただきます。

querySelectorAllとforEachとは

[querySelectorAll]

→HTMLに存在する複数の要素を取得することができる(liタグを一気に取得するようなイメージ)

特徴
・class名、id名、タグ名、どこからでも要素を取得できる。
単数を取得するquerySelectorと複数を取得するquerySelectorAllでほとんど用途が足りてしまうのではないかというほど、便利なメソッド
・nodeListという状態で取得することになるので、少し工夫して処理を加える必要がある

[forEach]

→querySelectorAllで取得した要素や配列などに、繰り返しの処理をすることができる

特徴
・以前は「for」で表現されることが多かった繰り返し処理(ループ処理)に代替される形で、モダンJavaScriptで主流の繰り返し処理記法になっている
・類似メソッドとして、map、filter、sliceなどがある

基本の書き方

まずは基本から始めてみます。

以下のように四角い要素を4つ用意します。

See the Pen Untitled by shinobi (@shinobi-hattori) on CodePen.

 

次に、変数を定義して4つの要素をquerySelectorAllで取得します

const box = document.querySelectorAll(‘.box’);

querySelectorAllを使用する場合は、CSSを記述する場合と同じようにclass名であれば「.」、idであれば「#」をつける必要があります。

ここにforEachを追記していきます。

forEachの基本的な書き方は以下のようになっています。

変数.forEach((element) => {
element.innerHTML = ‘テキスト’; //処理の内容
});

elementの部分は、現在ループで処理している要素を表しています。

いわゆる「引数」にあたります。

要素を表すためにelementと書いていますが、名前はelement以外でも大丈夫です。

また、処理を書く際は、

変数.innerHTML = ‘テキスト’;

のように毎回変数名を書く必要がなく、要素を指定する変数の部分はelementに置き換わります。

これを踏まえ、デモのscriptを追記していきます。

const box = document.querySelectorAll(‘.box’);

box.forEach((element) => {
 element.innerHTML = ‘boxです’;
});

ここまでで以下のようになります。

全ての要素にまとめて処理をすることができました。

See the Pen Untitled by shinobi (@shinobi-hattori) on CodePen.

クリックイベントと組み合わせる

より実用的にしていくため、forEachの全体処理をクリックイベントで変化するようにしていきます。

HTML要素に <button class=”btn”>ボタン</button>を追記し、CSSを整えます。

.btn {
width: 100px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
}

続いて、button要素を取得します。

要素の取得はquerySelectorAllの単数系のquerySelectorです。

const btn = document.querySelector(‘.btn’);

クリックイベントの基本形が

変数.addEventListener(‘click’, () => {
//ここに処理を書く
});

なので、 ここの処理の部分に先ほどのforEachの内容を入れてしまって、

const box = document.querySelectorAll(‘.box’);
const btn = document.querySelector(‘.btn’);

btn.addEventListener(‘click’, () => {
 box.forEach((element) => {
   element.innerHTML = ‘boxです’;
   });
 });

このようになります。

ここまでの全体が以下の通りです。

ボタンクリックのイベントをきっかけに、要素全体の処理ができているかと思います。

See the Pen Untitled by shinobi (@shinobi-hattori) on CodePen.

引数のインデックス番号も使う

forEachの処理内容に渡すことができる値(引数)は、先ほどのelement以外にも「インデックス番号」を渡せるように設定されています。

インデックス番号とは、例えば要素を4つ取得したとしたら、1つ目の要素から0、1、2、3という番号が割り振られている値のことです。

このインデックス番号の引数を使うことで、さらに応用した処理をすることができます。

書き方は、

変数.forEach((element,index) => {
  element.innerHTML = `番号${index}`;
});

のようになります。

上記の例のようにテキストと組み合わせて使う場合は、テキストを囲んでいるクオーテーションが「バッククオーテーション」になり、indexという引数を入れたい部分には${}で囲う必要があります(テンプレートリテラルという記法)。

これまでの例と組み合わせると

const box = document.querySelectorAll(‘.box’);
  const btn = document.querySelector(‘.btn’);

btn.addEventListener(‘click’, () => {
  box.forEach((element,index) => {
   element.innerHTML = ‘box${index}です’;
  });
});

このように書くことができます。

その他、クリックした際に色それぞれboxの色が変わったりと、様々な処理を追加したものが以下の結果です。

インデックス番号を利用することによって、共通の全体処理と、それぞれの処理を分けることができています。

See the Pen Untitled by shinobi (@shinobi-hattori) on CodePen.

その他の例

これまでの例以外にも、2つの例を作成しました。

1つ目は、to doリストのようなものを想定しています。

左側のリストをクリックすることによって、リストを右側に移動させることができます。

See the Pen Untitled by shinobi (@shinobi-hattori) on CodePen.

 

要素を移動させることができる「appendChild()メソッド」を使うことで作ることができます。

2つ目は、簡単なクリックゲームです。

See the Pen Untitled by shinobi (@shinobi-hattori) on CodePen.

 

forEachをaddEventListenerの外側に記述することで、複数要素のクリックイベントを個別に分けることができます。

さいごに

JavaScriptを始めたばかりの頃は、要素のひとつひとつに処理を書いていましたが、複数要素の処理を覚えたら効率が飛躍的に上がりました。

ループ処理のモダンな記法であるforEachは、ぜひquerySelectorAllとセットで使ってみてください。

おすすめ記事