アンケートサイトで使える!性別のラジオボタンを自動選択するブックマークレット
アンケートサイトで使えそうなブックマークレット、第4弾。
「あなたの性別を選択してください」といった設問で、ラジオボタンを自動選択するブックマークレットを作った。
目次
サンプル
サンプルは以下より、「Select Gender」を操作してみてほしい。
- デモ : Survey Helpers Parts
- コード : frontend-sandboxes/survey-helpers-parts.html at master · Neos21/frontend-sandboxes
ブックマークレットコード
ブックマークレット用のコードは以下。
javascript:((G,L,A)=>{A=[],Array.prototype.forEach.call(document.querySelectorAll('input[type="radio"]'),(e,n,r,o)=>{if(!A.includes(e.name))for(n=e,r=!1,o=L;o--;)r||((n=n.parentNode).innerHTML.includes(G?'女':'男')?r=!0:n.innerHTML.includes(G?'男':'女')&&(e.checked=!0,r=!0,A.push(e.name)))})})(!1,3);
末尾の (!1,3)
部分がユーザ設定項目。!1
と書くと false
の意味になるので、「女性」ラジオボタンを選択する。!0
だと true
の意味になるので、「男性」ラジオボタンを選択する。選択したい方の性別にあった Boolean 値を設定する。
3
は、テキストボックスの周辺を探索する範囲を指定するモノ。前回の記事で触れたのと同じ仕組みで、対象のラジオボタンからどれだけ親要素に遡って探索するか、という指定。上手くラジオボタンが選択できないようであれば、3〜10くらいの間で数値を増やしていってもらえれば上手く行くかと。
ソースコード
元のコードは以下のとおり。
/**
* 任意の性別のラジオボタンを選択する
*
* @param gender true で男・false で女を選択する
* @param loop 親要素を遡るループ回数。テキストボックスを起点に、親要素に遡って innerHTML に「歳 or 才」の字がないか探すので、
* 対象のページ構造に合わせてループ回数を指定しておく。大体 3〜5 階層くらいで良いかと
*/
function selectGender(gender, loop, ARRAY) {
// 引数 ARRAY は引数としては利用せず、ローカル変数の宣言回避のために引数の形を取っている
ARRAY = [];
Array.prototype.forEach.call(document.querySelectorAll('input[type="radio"]'), (radio, parent, finished, i) => {
if(!ARRAY.includes(radio.name)) {
parent = radio;
finished = false;
for(i = loop; i--;) { // 親要素を遡る
if(!finished) {
parent = parent.parentNode;
if(parent.innerHTML.includes(gender ? '女' : '男')) {
// 選択した方と逆の性別が含まれている場合
// このラジオボタンを起点とした探索を終わらせる
finished = true;
}
else if(parent.innerHTML.includes(gender ? '男' : '女')) {
// 選択した方の性別が含まれている場合
radio.checked = true;
finished = true;
// 一度選択したラジオボタン群を無視するため、ラジオボタンの名前を控えておく
ARRAY.push(radio.name);
}
}
}
}
});
}
基本的なやり方は前回の「年齢自動入力ブックマークレット」と同様。input[type="radio"]
な要素を取得し、その親要素に遡って innerHTML
を調べた時に、'男'
か '女'
の文言を含んでいれば、それを性別選択のラジオボタンと認識して操作する、というモノ。
今回はラジオボタンなので、同じ name
属性を持つ input[type="radio"]
が最低2つは登場することになるであろう。そのため、操作したラジオボタンの name
属性を控えておき、一度操作したラジオボタン群は次以降無視するようにした。
単純に親要素に遡って innerHTML
を見ていく関係上、選択したい性別とは別の項目まで調べてしまうことがあったので、その解決にちょっと手間取った。
どういうことかというと、例えば、性別選択ラジオボタンは以下のような HTML 構造になっていることが多いであろう。
<ul>
<li><input type="radio" name="gender" value="1"> 男性</li>
<li><input type="radio" name="gender" value="2"> 女性</li>
</ul>
ココで「女性を選択したい」とする。input[type="radio"]
を順に取得するので、最初は value="1"
、つまり「男性」用のラジオボタンを取得する。このラジオボタンを起点に親要素に遡っていくと、「女」の文字が見つからないので ul
要素まで遡る。そうすると ul
要素の innerHTML
から「女性」の文言が拾えてしまい、男性用のラジオボタンを間違って選択してしまうのである。
コレを回避するため、「選択していない性別が出てきたら、そのラジオボタンに対する処理を止める」という作りにした。つまり、「女性」を選択した時に、そのラジオボタンの近くに「男性」の文言が見つかったら、そのラジオボタンの処理を中断し、次のラジオボタンの探索に移る。そして2つ目のラジオボタンの周辺から「女性」を見つけたら、処理を中断しつつ、「操作済みのラジオボタン」として配列に name
属性を控えておくのである。こうしておけば、性別選択の中に「その他」などがあっても無視できる、というワケ。
やっていることは些細なことだが、コレでラジオボタンをイチイチポチポチしなくて良くなった。
↓ ここまでの記事の総まとめ。