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
で回す方法をコピペ用に残しました。自分用ですが、よろしければみなさんもご活用ください。