この記事を書いた背景
JavaScriptの『querySelector()メソッド』を使って、任意のHTMLを取得する処理を記述していたのですが、最初、うまく取得することができませんでした。
うまく取得できなかった理由は、取得するHTMLを指定する際に記述したname属性の指定コードがうまく書けていなかったためです。
今回はname属性を指定するひと工夫も含め、querySelector()使用時の注意点を書いていきたいと思います。
そもそもquerySelector()メソッドとは
JavaScriptのメソッドで、任意のHTMLを取得するメソッドです。
指定したセレクタに一致する最初のHTML要素(Element)を取得するメソッドです。
『document.querySelector( CSSセレクタ )』のように使います。
実際の使い方は下記の例をご覧ください。
自分がどのようにつまづいたか
オリジナルアプリを作成中、ラジオボタンの実装を行ってましたが、
選択したボタンの値を取得する処理がうまく機能しない場合がありました。
下記の例で見ていきたいと思います。
<!--ラジオボタンの記述。iPhoneかAndroidかを選ぶラジオボタン-->
<group class="inline-radio">
<div>
<input type="radio" value="1" name="simulation[phone]" id="simulation_phone_1">
<label for="simulation_phone">iPhone</label>
</div>
<div>
<input type="radio" value="2" name="simulation[phone]" id="simulation_phone_2">
<label for="simulation_phone">Android</label>
</div>
</group>
//ラジオボタンの要素(NodeList)を取得する
const phone_list = document.getElementsByName('simulation[phone]');
//取得したラジオボタンの要素(NodeList)をラジオボタン1つずつ取り出し、変数eに格納する。
phone_list.forEach(function(e) {
//クリック(ボタン押下)された要素eの場合イベント発火
e.addEventListener("click", function() {
//クリックされたinputタグの値(value値)を取り出し、変数phone_planに格納する
const phone_plan = document.querySelector("input:checked").value;
//変数phone_planの出力
console.log(phone_plan);
});
});
※NodeListは、ざっくり言えばHTMLの情報全てが詰まったオブジェクトです。
簡単なHTMLとJSがあります。色々端折ってますがご了承ください。
見た目的には簡単なラジオボタン(●iPhone ●Android)があるだけです。
ラジオボタンでiphoneを選択すると、検証ツールのconsoleにて 1 が出力されます。
1
普通に値は取得できました。
しかし、HTMLにラジオボタンで実装された質問等がいくつも有り(スマホを選ぶラジオボタン・PCを選ぶラジオボタン...など)、それぞれのラジオボタンの押下された値を取得する処理を書くときに問題が起きます。
記述を見直さないといけないのは、JSの『querySelector()メソッド』です。
querySelector()メソッドが取得する要素の位置は...
先程も書きましたが、『querySelector()メソッド』で取得するのは、**指定したセレクタに一致する最初のHTML要素(Element)**です。
そのため、現状の『querySelector("input:checked")』のような形でクリックされた要素を取得しようとすると、複数種類のラジオボタンがあるなかで、HTMLの一番上にあるラジオボタンの選択された値が取得されてしまい、HTMLの一番上にあるラジオボタン以外うまく値が取得できません。
querySelector()メソッドにおけるname属性の指定
そこで色々調べたところ、name属性を指定すれば良さそうです。
下記のように修正してみました。
//修正前
const phone_plan = document.querySelector("input:checked").value;
//修正後
const phone_plan = document.querySelector("input:checked[name=simulation[phone]]").value;
このように修正すれば、『name属性がsimulation[phone]のラジオボタンでクリックされた要素』のように指定できるはず。
不正なセレクタということで、値が取得できないようです。(例とname属性違いますがご容赦ください。。。)
//この書き方は正しい
querySelector("input:checked[name=name属性名]]")
という書き方は正しいのですが、クラスが指定されたname属性(今回で言ったら、simulationクラスのname属性「phone」)の場合は、上記の書き方では通用しないようです。(角括弧まみれになるからかな??)
ということで、今度はクラス名外してみました。
//修正前
const phone_plan = document.querySelector("input:checked").value;
//1回目修正後
const phone_plan = document.querySelector("input:checked[name=simulation[phone]]").value;
//2回目修正後
const phone_plan = document.querySelector("input:checked[name=phone]").value;
name属性がphoneのvalue値はなんにもないよ〜というエラーです。
正しいname属性は『simulation[phone]』ですからね。
やはり、クラス名を取るだけほど甘くない世界だ。
そして、ついにLGTMな書き方発見。
ということで、このようにname属性を指定すればいいというのを見つけました。
//修正前
const phone_plan = document.querySelector("input:checked").value;
//1回目修正後
const phone_plan = document.querySelector("input:checked[name=simulation[phone]]").value;
//2回目修正後
const phone_plan = document.querySelector("input:checked[name=phone]").value;
//3回目修正後(LGTM)
const phone_plan = document.querySelector("input:checked[name*=phone]").value;
name属性の指定のところで『*』を入れました。これは『部分一致検索』を意味します。
今回で言ったら、name属性に『phone』が含まれてるname属性という指定方法です。
ということで、無事、値が取得できました。
1
あとは、name属性の命名に気をつけながらname=*を使いこなしていけば、自分の思い通りのアプリが実装できると思います!
セレクタの様々な指定方法
ちなみにセレクタの指定方法は、name*=以外にもたくさん種類があります。
https://hakuhin.jp/js/selector.html
こちらのサイトにセレクタの書き方が詳しく載っているので、ぜひ見てみてください。
色んな属性の指定方法があって、実装の幅が広がりますね。大変参考になりました。