JavaScript indexOfの使い方
HTMLの要素の順番を取得する、と勝手に理解していたJavaScriptの「indexOf」。
実際は順番は返すんだけど、検索してその検索対象の要素の順番を返すメソッドだと知りました。
適当に覚えすぎていたので、使い方と構文を理解していきたいと思います。
indexOfはこんな時に使います
大体の使用目的はindexの番号を取得したいときに使います。
例えば、「ul」の中にある「li」の順番を取得したいときや、配列に入れた要素の順番を取得したいときなど。
その他、単純に文字検索をして、その検索対象の開始位置がどこにあるかなどにも使います。
使用例 クリックしたliのインデックス番号を返す
よく使うパターンとしてクリックした要素のindex番号を取得したい、というのがあります。
今回はそのサンプルを。
- 1番目の要素
- 2番目の要素
- 3番目の要素
- 4番目の要素
結果:リストをクリックすると番号を表示します
リストの番号は「1」から始まりますが、indexは「0」から始まります。
サンプルのHTMLとJavaScript
<ol id="sample_01"> <li>1番目の要素</li> <li>2番目の要素</li> <li>3番目の要素</li> <li>4番目の要素</li> </ol> <p>結果:<span id="result_1">リストをクリックすると番号を表示します</span></p> <script language="javascript"> //対象の要素を取得 let sample_01 = document.querySelectorAll("#sample_01 li"); //対象の要素を配列化 let sample_array = [].slice.call(sample_01); //for文で配列を回す for (let i = 0; i < sample_01.length; i++){ //クリック対象を取得 sample_01[i].addEventListener('click', (e) => { //indexOfでインデックス番号を取得 let get_index = sample_array.indexOf(sample_01[i]); //インデックス番号を返す要素を取得 let set_text = document.getElementById("result_1"); //インデックス番号を表示 set_text.innerHTML = get_index; }); } </script>
liインデックス番号取得のコードの解説
クリックした「li」のインデックス番号を取得するコードの解説です。
対象の要素を取得 → 「li」を指定
//対象の要素を取得
let sample_ol = document.querySelectorAll("#sample_ol li");
インデックス番号を取得したい要素を取得します。
今回はリストのインデックスが欲しいので、「ol」の子要素の「li」を取得します。
liを指定しない場合、「ol」が1つしかないので、「0」しか返ってきません。
対象の要素を配列に変換する
//対象の要素を配列化
let sample_array = [].slice.call(sample_01);
リストとして取得するのであれば、配列化する必要はないのですが、indexOfで使用する場合、配列化する必要があります。
配列化したものと、してないものをコンソールログで確認してみます。
sample_01(配列化してない)のコンソールログの中身
NodeList(4) [li, li, li, li]
0: li
1: li
2: li
3: li
length: 4
[[Prototype]]: NodeList
sample_ol(配列化したもの)のコンソールログの中身
(4) [li, li, li, li]
0: li
1: li
2: li
3: li
length: 4
[[Prototype]]: Array(0)
パッ見はおんなじに見えるわけですが、Prototypeが「NodeList」と「Array(0)」とちゃんと別物になっているのがわかります。
lengthでfor文を回す
//for文で配列を回す
for (let i = 0; i < sample_01.length; i++){
sample_01.lengthと指定すると、要素の数だけ繰り返します。
ちなみに、「sample_array.length」でも同様に繰り返します。
ここのfor文は「li」タグの全てを対象にし、「li」の数だけ同じ処理をさせるため。
クリックイベントを仕込む
//クリック対象を取得
sample_01[i].addEventListener('click', (e) => {
sample_01は「li」が代入されています。
その「li」の[i](0~3)を指定し、クリックされた対象に対しての処理を書きます。
indexOfで番号を取得
//indexOfでインデックス番号を取得
let get_index = sample_array.indexOf(sample_01[i]);
ここでようやく「indexOf」の登場です。
indexOfは「配列」が対象の場合、検索対象が何番目にいるか、を返してくれます。
そのため、配列化した「sample_array」から、検索対象である「sample_01[i]」のインデックス番号が返ってきます。
ちなみに配列化してない、「sample_01」でindexOfを実行すると以下のエラーが返ってきます。
▼エラーメッセージ
Uncaught TypeError: sample_01.indexOf is not a function
取得した番号を表示
//インデックス番号を返す要素を取得
let set_text = document.getElementById("result_1");
//インデックス番号を表示
set_text.innerHTML = get_index;
最後に、取得した番号を返す処理を記述して完了です。
解説の途中で気づいたこと。。 indexOfいらなくない?
自分で解説してて気づいたんですが、クリックしたliのインデックス番号が欲しいだけなら、indexOfいらなくないか?と。
「i」でクリックした順番取得してるはずなので、それを使えば問題ないのでは?
と思い検証したらやっぱりそれで問題ありませんでした。
まぁ、indexOfの解説記事なので、、使い方はあってるので良しと。。
indexOf使わない版
indexOfを使わないと、配列化も必要なくなりコードがかなりスッキリしました。
<script language="javascript"> let sample_01 = document.querySelectorAll("#sample_01 li"); for (let i = 0; i < sample_01.length; i++){ sample_01[i].addEventListener('click', (e) => { let set_text = document.getElementById("result_1"); set_text.innerHTML = i; }); } </script>
そもそもインデックス番号の取得はindexOfを使う必要があるという、先入観が私の中にあったので、それを払拭できて良かったです。
JavaScript indexOfのまとめ
なんとなくで使っていたindexOfですが、今回の記事を作ることで仕様がよく理解できました。
なんで「ul」や「ol」で取得できなかったのかが理解できました!
勘違いの原因はNodeListと配列の違いを理解してなかったため。
理解してないというか違いを意識したことすらありませんでした。
NodeListで「length」は扱えるという仕様がわかりづらくしている感がありますね。
便利だから助かるんだけど。
これからは「NodeList」と「配列」を意識してコードを書けます。
自分の無知をさらけ出した記事でしたが、賢くなれたので非常に良い記事になりました。