Corredor

ウェブ、プログラミングの勉強メモ。

アンケートサイトで使える!テキストボックスに年齢を自動入力するブックマークレット

Excel VBAでIEを思いのままに操作できるプログラミング術 Excel 2013/2010/2007/2003対応

Excel VBAでIEを思いのままに操作できるプログラミング術 Excel 2013/2010/2007/2003対応

アンケートサイトで使えそうなブックマークレット、第3弾。「あなたの年齢を入力してください」といった設問で、テキストボックスに年齢を自動入力するブックマークレットを作った。

サンプル

サンプルは以下の CodePen より、「Set Age」を操作してみてほしい。

See the Pen Survey Helpers by Neos21 (@Neos21) on CodePen.

ブックマークレットコード

ブックマークレット用のコードは以下。

javascript:((A,L)=>{Array.prototype.forEach.call(document.querySelectorAll('input[type="text"]'),(e,r,n,t)=>{for(r=e,n=!1,t=L;t--;)n||((r=r.parentNode).innerHTML.includes('歳')||r.innerHTML.includes('才'))&&(e.value=A,n=!0)})})(25,3);

末尾の (25,3) 部分がユーザ設定項目。25 は自動入力したい年齢。3 は、テキストボックスの周辺を探索する範囲を指定するモノ。詳しくは後述するが、上手く年齢が自動設定できないようであれば、3〜10くらいの間で数値を増やしていってもらえれば上手く行くかと。

ソースコード

元のコードは以下のとおり。

/**
 * 周辺に「歳」か「才」の字があるテキストボックスに年齢を設定する
 * 
 * @param age 設定する年齢
 * @param loop 親要素を遡るループ回数。テキストボックスを起点に、親要素に遡って innerHTML に「歳 or 才」の字がないか探すので、
 *             対象のページ構造に合わせてループ回数を指定しておく。大体 3〜5 階層くらいで良いかと
 */
function setAge(age, loop) {
  Array.prototype.forEach.call(document.querySelectorAll('input[type="text"]'), (text, parent, finished, i) => {
    parent = text;
    finished = false;
    for(i = loop; i--;) {  // 親要素を遡る
      if(!finished) {
        parent = parent.parentNode;
        if(parent.innerHTML.includes('歳') || parent.innerHTML.includes('才')) {
          text.value = age;  // 年齢を設定する
          finished = true;
        }
      }
    }
  });
}

お察しの良い方ならお分かりであろう。このブックマークレットは、input[type="text"] 要素の周辺に「歳」か「才」の文言があれば、そのテキストボックスを「年齢入力欄」と見なして、指定の年齢を自動入力する、というシロモノだ。

input[type="text"] 要素自身の name 属性や id 属性を見ても、アンケートサイトの場合は「age」とか「nenrei」みたいな名称が振られているワケではない。だからテキストボックスだけを見てもそれが「年齢入力欄」なのかどうか区別が付かない。

しかし、大抵の場合、テキストボックスの隣に「歳」という文言が書かれており、コレによって人間は「年齢を入力する場所だ」と認識しているはずだ。

ということで、テキストボックスを包括する親要素に遡り、周辺に「歳」の字が含まれていないか検証している、というワケだ。

<label><input type="text"></label>

といった作りであれば、テキストボックスの最初の親要素である label 要素の innerHTML を見て「歳」の字が含まれていることを確認できるので、コレに年齢を設定すれば良い。

しかし、サイトによっては以下のように、

<tr>
  <td>
    <span>
      <input type="text" id="q1">
    </span>
  </td>
  <td>
    <label for="q1"></label>
  </td>
</tr>

テキストボックスと「歳」の字の間に様々な要素が挟まっている場合がある。こうなると、テキストボックスの直接の親要素 (この場合 span) 要素に遡っただけではダメで、tr 要素にまで遡って innerHTML を見ないと判定できない。

コレが、関数の第2引数になる loop 変数、ブックマークレット用コードでいうところの 3 の正体。「親要素の親要素」へと遡っていくループ回数を指定するためのモノだ。サイトの構造にもよるが、大体3〜5階層ぐらい上に遡れば、対象のテキストボックスが年齢入力欄かどうか判定できるだろう。

年齢入力欄と判断して年齢を自動設定した後は、ループを抜けるようにしているので、余計な処理はしないようにしている。

たったコレだけの仕組みで、完璧に動作するワケではない場合もあるとは思うが、大抵のアンケートサイトにおいて「テキストボックスを選択して2桁の年齢を入力する」という手間が1クリックに短縮できた。