JavaScript

querySelectorAllで取得した要素をforEachで回す

JavaScriptで、document.querySelectorAll()で取得した要素をforEachで回す方法をコピペ用に残します。
他にも方法はありますが、IEのサポートを考えなくてよければ記述が短くて済むので、forEachで良いと思います。

ただし、後述するようにforEachは途中で処理を抜けることができないので、breakステートメントを使って処理を途中で抜けたい場合はfor...ofループなどを用いましょう。

querySelectorAll()について

querySelectorAll()メソッドは、同一のCSSセレクターが付いた要素を全て配列で格納することができます。CSSセレクターは、HTMLのclass属性の値を用いた要素の特定方法です。

<div class="wrapper-01">
   <div class="block"></div>
   <div class="block"></div>
   <div class="block"></div>
</div>

例えばこのHTMLに対して、
const blocks = document.querySelectorAll('.wrapper-01>.block');

とJavaScriptで書けば3つのblockというクラス名がつけられたdiv要素が取得できます。
配列の変数名を英単語の複数形にして、1つずつの変数をその英単語の単数形にするというのが慣例です。

ここでは、すべての要素が格納された配列の変数名をblocksとし、ひとつひとつの変数名をblockと定義した例でこのあとコードをご紹介します。

クラス名で取得できる場合は、getElementsByClassName()を使った方が処理が早くなりますので、getElementsByClassName()についても後述します。
また、querySelectorAll()を使う場合も、CSSセレクターは極力単純にした方が処理速度が速くなります。例えば(.hoge .wrapper-01>.block)とするよりも、(.wrapper-01>.block)の方が処理速度が速いということです。

なお、document.querySelectorAll('.block')はjQueryで$('.block')と書くのと同じです。
jQueryで書くと短く済み、それがjQueryの良さの一つとは言えますが、jQueryの存在意義の最たる部分はIneternetExplorerでも動くブラウザ互換にありました。その意味で、もはやお役御免で、サポート終了の未来が私には見えます。脱jQueryという言葉があるように、jQueryはもう使わないようにしていくことをおすすめします。

querySelectorAll()で取得した要素をforEachで回す方法

アロー関数を用いる場合

<script>
const blocks = document.querySelectorAll('.wrapper-01 > .block');
blocks.forEach( block =>{
   //処理
});
</script>

アロー関数というのは、function(block)block=>と書き換えられるものです。簡略化のための記法ですね。たいして文字数変わらないと思いますが・・。少しでも短くなる方で慣れておいた方が良いとは思います。

アロー関数を用いない場合

const blocks = document.querySelectorAll('.wrapper-01 > .block');
blocks.forEach( function( block ){
   //処理
});

アロー関数を使わない場合はこのようになります。

indexを取得する場合

const blocks = document.querySelectorAll('.wrapper-01 > .block');
blocks.forEach( ( block , index ) => {
   //処理
});

このように書くと、ここで言う変数blockが何番目であるかがindexに数値として入ります。なので、処理を記述するところでindexの値を用いることができます。

この時注意なのが、documentquerySelectorAll()で取得した値(ここで言うblocks)は配列であり、indexは0から始まるというところです。

例えば次の例は、indexが1の場合、すなわち2番目のblockだけclass名にhogeを加えるという処理となります。

const blocks = document.querySelectorAll('.block');
blocks.forEach( ( block , index ) => {
   if( index == 1 ){
      block.classList.add('hoge');
   }
});

注意事項:ループを抜けたいとき

foreachは途中で処理を抜けることができません。例えばbreakステートメントや、returnステートメントを利用してもダメです。

現状、ループを途中で抜けたい時は以下のいずれかのメソッドを利用になりますが、for...ofループの方がforEachループに似ているので、そちらが良いかと思います。forループは昔からあるもので、慣れている方はそちらでも良いかとは思います。

for…ofループ

for (const blocks of block) {
    if (block.textContent === 'hoge') break;
}

forループ

for (let i = 0; i < blocks.length; i++) {
if (blocks[i].textContent === 'hoge') break;
}

querySelectorAll()の関連メソッド

document.querySelectorAll()に関連するメソッドをご紹介します。最初のdocument.querySelector()は、たまに私はdocument.querySelectorAll()と書き間違えてしまうことがあります。みなさんは間違わないようにしましょう。

querySelector()

querySelectorAll()が複数要素を取得するためのものであるのに対して、querySelector()は、単一の要素を取得します。

指定方法はquerySelectorAll()と同じで、CSSセレクタ―です。
同一のCSSセレクタ―が同ページ内にある場合には、一番最初の要素を取得します。

getElementById()

getElementById()はid属性の値で要素を取得します。idはページ内に1つしか設けられない仕様なので、取得する対象は1つです。

例えばid="hoge"の要素を取得する場合は、document.getElementById('hoge')と書きます。

getElementsByClassName()

getElementsByClassName()はclass属性の値で要素を取得します。querySelectorAllと同様に複数の要素を取得でき、その後、foreachでの回し方も同様です。先述の通り、CSSセレクタ―ではなくクラス名で取得できる場合は、こちらの方が処理速度が速いので、getElementsByClassName()を使った方が良いと言えます。

例えばclass="hoge"の要素を取得する場合は、document.getElementByClassName('hoge')と書きます。

getElementsByName()

getElementsByName()はname属性の値で要素を取得します。querySelectorAllと同様に複数の要素を取得でき、その後、foreachでの回し方も同様です。
用途としては、ラジオボタンで用いられます。ラジオボタンは同じname属性の値のものを一つのグループとして扱われるためです。

まとめ

documentquerySelectorAllで取得した要素をforEachで回す方法をコピペ用に残しました。自分用ですが、よろしければみなさんもご活用ください。

著者のイメージ画像

株式会社BringFlower
稲田 高洋(Takahiro Inada)

2003年から大手総合電機メーカーでUXデザインプロセスの研究、実践。UXデザイン専門家の育成プログラム開発。SEOにおいても重要なW3Cが定めるWeb標準仕様策定にウェブアクセシビリティの専門家として関わる。2010~2018年に人間中心設計専門家を保有、数年間ウェブアクセシビリティ基盤委員も務める。その後、不動産会社向けにSaaSを提供する企業の事業開発部で複数サービスを企画、ローンチ。CMSを提供し1000以上のサイトを分析。顧客サポート、サイト運営にも関わる。
2022年3月に独立後、2024年4月に株式会社BringFlowerを設立。SEOコンサルを活動の軸に据えつつ、AIライティングツールの開発と運営を自ら行う。グッドデザイン賞4件、ドイツユニバーサルデザイン賞2件、米国IDEA賞1件の受賞歴あり。