リフォーム大作戦

このページではウェブページで使用されるフォーム要素( <form>〜</form> )について、より使いやすい物にするために、いわゆる TIPS というかそんな感じの技術をいろいろと。

HTML

label 要素

ラジオボタンやチェックボックスなどは、もちろんウェブページのフォーム専用というわけではなく、通常のアプリケーションでも設定画面などでよく目にすることと思いますが、そういった場合は実際にチェックが入る部分だけでなく、説明文のほうをクリックしてもオン・オフが可能になっていると思います。

NC 4.78 の設定画面 エクスプローラのオプション画面

こちらの画像はそれぞれ Windows 95 の Netscape Communicator 4.78 (編集 -> 設定 -> 詳細)とエクスプローラ(表示 -> オプション)の設定画面です。画面キャプチャーですとマウスカーソルが映らないようなのであれですが、パソコンからご覧になっている方でしたら、特に補足するほどのこともありませんですね。要は「自動的に画像を読み込む」や「すべてのファイルを表示」をクリックしても、きちんとオン・オフされるということで。

一方、ウェブページの form 要素で使われる場合は、ラジオボタンやチェックボックスなど、チェックを入れるその部品自体をクリックしなければ、オン・オフできない作りになっている場合が多いようですが、それはなぜかといえば、その説明文とフォームの各部品がはっきりと関連付けられていないためだと思われます。これが送信ボタンなどでしたら、 value 属性の値がボタンのラベルとして表示されますから他に解釈のしようもありませんが。

例えば以下は、メールアドレスを登録し、さらにお知らせなども受け取るかどうかを送信するためのフォームの例(ソース & 実際の表示)ですが、少なくとも HTML 的には間違っていませんし、各部品( input 要素 )とその隣りのテキストとは一見関連があるように見えます(そしてそういう意図で配置されています)が、しかし必ずしも近くに存在するテキストがその部品と関係があるとは限らないわけです。

<form action="regist.cgi">
  <p>メールアドレス: <input type="text" name="mail"></p>
  <p>お知らせメールを</p>
  <ul>
    <li><input type="radio" name="news" value="on">希望する</li>
    <li><input type="radio" name="news" value="off">希望しない</li>
  </ul>
  <p><input type="submit" value="登録"></p>
</form>

フォームの表示例

例えば希望する場合はどうこう、希望しない場合はどうこうといった説明文が、同じ要素内(上記の例ですと <li>〜</li> 内)に存在するかもしれませんし、一つの要素(例えば <p>〜</p> 内)の中に複数の部品とそれに対応したラベルをずらずらと並べるケースももちろんありえます。またこのようなシンプルな例ならまだしも、 table 要素で表を作って多くの項目を記入してもらう場合、各部品とそのラベルが、ソース上では遠く離れた場所に位置するケースも考えられます。

つまりそれらのケースでは、実際にブラウザで表示して人の目で見ているからこそ、文章の意味や見かけ上の位置関係によって、この文字列はこのチェックボックスに関連しているのだろうと推測できるのであって、ソースを直接解釈して表示するブラウザから見れば、どの文字列のどこからどこまでがどの部品と対応しているかなんてわかりませんし、それがわからなければ、横の説明をクリックした時にチェックを入れるといったサポートもできないわけです。

しかし逆に言えば、人の目にはわかりづらくとも、ソース上で関連付けられてさえいれば、ブラウザは関連性を認識して如何様にも利用することができるわけです。もちろんブラウザが対応しているかどうかは別問題ですし、もとより見た目でもわかりやすいほうが良いのは言うまでもありませんが。

そこで文字どおり登場するのが label 要素というわけです。この要素は文字どおり(フォームの各部品に対して)明確に関連付けられたラベルを提供します。具体的には label 要素の for 属性に、各 input 要素につけた id を指定するんですが、何より実際にご覧頂くのが話が早いかと。

<form action="search.cgi">
  <p>
    <label for="t">タイトル</label>
    <input type="text" name="title" id="t" value="北へ。">
  </p>
  <ul>
    <li>
      <label for="dc">
        <input type="radio" id="dc" name="hard" value="DC">ドリームキャスト
      </label>
    </li>
    <li>
      <label for="ps2">
        <input type="radio" id="ps2" name="hard" value="PS2">プレイステーション2
      </label>
    </li>
  </ul>
</form>

まずこんな感じで各 input 要素に id を追加し、関連付けたい文字列を label 要素としてマークアップして、その for 属性の値として先ほどの id を指定します。すると実際のフォームは以下のような感じになります。

label 要素に対応しているブラウザであれば、フォームの部品ではなくラベル部分をクリックしても、テキスト入力可能な状態になったり、チェックが入ったりするはずです。今回は例に挙げていませんが、チェックボックスなど他の部品でももちろん同じことです。ちなみに Windows XP + Internet Explorer 6 ですと label 要素の上にカーソルを持っていったときに、その要素と関連する部品に変化が生じるようです。

また制作者のほうでも、 label 要素にスタイルシートで指定することで、さらに各部品と文字列の関連を強調したり、単純に装飾を加えたりすることができます。上記の例の機種名を表示している箇所ですが、例えば以下のような指定を行えば、ラジオボタンと機種名をセットにしてボーダーが引かれ、背景色なども設定できます。

label {
	border: 1px solid navy;
	color: black;
	background-color: #ccffff;
}

なお、上記の例で input 要素が label 要素の中だったり外だったりするのは間違いではなく、どちらでも構いませんし、例えば table 要素の中で使う場合など、全くかけ離れた場所にあっても構いません。 label 要素の for 属性と input 要素の id 属性が対応さえしていれば、それは明示的に関連付けられていることになります。

なお、このように部品もテキストも label 要素の中に放り込んだ場合は、 for や id を省略しても、やはり中のテキストは自動的に(こちらは暗黙のうちにですが)同じ label 要素中の部品と関連付けられたラベルとして扱われます。ただ、こちらの手法ですと IE が対応していないらしいですし、アクセス性の観点からも for と id で明示的に結び付ける方が好ましいとのことなので、そうしておけば間違いないかと。

てなわけで、可能なら全てのフォーム(特にラジオボタンとチェックボックス)で使用してほしいところですが、そうでなくてもウェブ上で商売などされている方は、フォームにこっそりこんな気配りをしておくとあるいはお客さんに喜ばれることもある、かもしれません(笑)。とはいえ頭から「フォームでは文字列をクリックしても無駄」と試しもしない可能性が大きいかもですが。

JavaScript

元々 Netscape 社が Netscape Navigator に実装したのが JavaScript の始まりなんですが、その後 Internet Explorer が JScript として実装したり、ECMA によって標準化されて ECMA Script という名になったりしているようです。

さらに HTML 中で指定する際にも、 language 属性( language="JavaScript1.x" )で指定したり、 type 属性( type="text/javascript" )で指定したりといった方法がありますし(ただし HTML 4 以降 language 属性は非推奨)、さらには type 属性で指定する際には、 text/javascript ではなく application/x-javascript を使うべきといった議論もあったりするわけですが。

そのあたり(特に後者)につきましては、確信を持ってこれこれこうすべきだと言えるほど造詣が深くありませんので、とりあえず置いといて、このページの例では全て <script type="text/javascript"> を使用します。

それと JavaScript については、名称等だけではなくブラウザごとの挙動や使える機能などにも少なからず違いがあって、そのために navigator オブジェクトを利用してのブラウザを振り分けるといった手法も存在するわけですが、ここで言及していくものについては、かなり基本的な部分ですのでおそらくそんなにはブラウザを選ばないのではないかと。

さらに本題に入る前に少し補足ですが。(スクリプト必須のゲームなどならともかく)基本的に JavaScript を使用する場合は、 JavaScript をオフにしておいても閲覧に支障がなく、オンにしてあればより便利といった使い方をすべきだと自分は考えていますし、こちらではそういったスクリプトのみを紹介していく方向で。

また、これは余談ですが JavaScript と Java (アプレット)は別物です。そこをごっちゃにしたままその手の掲示板などで質問すると、十中八九ツッコミが入ると思いますのでご注意を(笑)。

focus() メソッド

ということで本題。まずはページを読み込んだ時点で任意の要素にフォーカスする例を。

function fcs () {
	document.forms[0].elements[0].focus();
}
window.onload = fcs;

これはいちばんシンプルな例ですが、こういったスクリプトを head 要素( <head>〜</head> )内の script 要素( <script type="text/javascript">ここにスクリプト</script> )内に記述するか、あるいは外部 JavaScript ファイル( example.js 等)に保存して、 script 要素の src 属性で読み込むよう指定します( <script type="text/javascript" src="example.js"></script> )。

とりあえず書式やオブジェクトの指定方法などについては割愛しますが、この場合はウィンドウ( window )の読み込みを終えた時( onload )に fcs が呼び出され、 fcs がページ内のいちばん最初のフォーム( forms[0] )のいちばん最初の部品( elements[0] )にフォーカスを移します( focus() )。

そうすれば、マウスを動かしてフォームのテキストボックスなどをクリックしなくても、キーボードでの入力がすぐに行えるようになるわけです。

といっても伝言板などのようにどのみち複数のデータを入力しなければならないフォームではあまりありがたみがないと思いますが、検索エンジンのようにどこに何を入力するかが決まりきっているような場合や、多少ページの作りが込み入っていて、できるだけすんなりと入力箇所にナビゲートしたい場合などは役に立つのではないかと。

実はこの手法については Google という好例がありまして。外部ファイルではなく直接 HTML ファイルに記述してありますので、ソースがそのまま参考になるかと思いますが、ページの読み込みを終えた時に( Google の場合は <body onload="function_name()"> で指定していますが同じ理屈です)自動的に中央の検索窓にフォーカスが移るようになっています。

Yahoo! や goo など他のポータルサイトの場合は、ニュースや各種情報のように検索以外の目的の人も多いでしょうけれど、 Google については訪れる人のほとんどが検索目的でしょうから、まさに打ってつけのスクリプトなわけですね。