イベントハンドラは装置に依存しないよう論理イベントをあわせて指定する。
WCAG1.0 の ガイドライン9. 装置に依存しないように設計する 件について。
以前のエントリーではウェブ・アクセシビリティについての問題提起を少々「煽った」ような文章で書いてみたわけだが、コメントにも2chのエントリーにも「はてブ」のコメントにも「マイノリティ」がどうというような指摘が結構あった(Old Macユーザーであることを指して)。そもそもアクセシビリティに関する議論においては「少数派」と「開発コスト」みたいな話題がついてまわるものであるが、例えばマウスを使わずに他のデバイス(ボタン装置やキーボード等)を使っているケースというのはどういうケースだろう。
- 上肢体不自由の人 (注1)
- 音声ブラウザを使っている人
- テレビでウェブを閲覧(リモコン操作)している人
- 携帯電話でウェブを閲覧している人 (注2)
そもそもノートPCでマウスを使えない時、トラックパッドが扱いづらくてキーボード操作する時が(僕の場合は)ある。TabキーとEnterキーでリンクを移動するのだ。
- (注1)
- IBMのパソコンのキーボードの真ん中にある(何と言う名前かは知らないが)赤いボタン(マウスポインタを移動させることができる)を口にくわえたペンのようなもので操作しているところを見学させていただいたことがある。この場合はキーボードやボタン装置ではなく、マウス前提のイベントハンドラでの操作となる。
- (注2)
- WCAG2.0(ワーキング・ドラフト) にあるように、将来のことも見据えておかねばならない。
- (注3)
- Mozilla系のブラウザでは、フォーカスされた状態で Tabキーを押すと onkeypress イベントが発生してしまう。最近のブラウザではフォーカスされた状態で Enter(Return)キーを押すとマウスクリックと同等の動作をするから(MacIEでは動作しない)onkeypress は敢えて指定しないか Tabキーが押された時を例外として処理する等の検討が必要。
ということで mouseover 等の物理イベントには onfocus 等の論理イベントをあわせて指定する必要がある。
| 物理イベント | 論理イベント |
|---|---|
| onmousedown | onkeydown |
| onmouseup | onkeyup |
| onclick | onkeypress (注3) |
| onmouseover | onfocus |
| onmouseout | onblur |
具体的には以下のようになる。
<a href="example.html" onmouseover="focusin()" onfocus="focusin()" onmouseout="focusout()" onblur="focusout()">サンプル</a>
長い、美しくない、面倒くさいとかいう話も出るだろうし、ここで「JavaScript and Accessibirity (1). - JavaScriptが前提の機能はJavaScriptで提供する」の考え方を適用する。
JavaScriptで実行したいイベント属性自体をJavaScriptでセットする方向で検討する。
参考:IE の getAttribute / setAttribute: Days on the Moon
JavaScript:
var isIE = (document.documentElement.getAttribute("style")
==document.documentElement.style);
// ブラウザ判別
function focusin(){
document.getElementById("status").innerHTML="Focus In";
}
function focusout(){
document.getElementById("status").innerHTML="Focus Out";
}
HTML:
<a href="example.html" id="tgtElement">サンプル</a>
<div id="status"></div>
bodyのonloadイベントでも良いし、適当な箇所でも良いので、イベント属性をセットするJavaScriptを追加。
JavaScript:
var tgt=document.getElementById('tgtElement');
if (isIE){
tgt.setAttribute("onmouseover", new Function("focusin()"));
tgt.setAttribute("onfocus", new Function("focusin()"));
tgt.setAttribute("onmouseout", new Function("focusout()"));
tgt.setAttribute("onblur", new Function("focusout"));
}else{
tgt.setAttribute("onmouseover", "focusin()");
tgt.setAttribute("onfocus", "focusin()");
tgt.setAttribute("onmouseout", "focusout()");
tgt.setAttribute("onblur", "focusout()");
}
function eventSet(tgt,fnction1,fnction2,fnction3,fnction4,ev1,ev2) として関数を作っておくとか、function eventSet(tgt,fnction,ev1,ev2) として、mouseover指定したら mouseout, onfocus, onblur を自動的に併せて指定するようなものを用意しておくとシンプルになるだろう。
別にイベント指定をXHTMLの中に直接書いても良いのだが、物理イベントと論理イベント両方を指定するのは面倒だという場合は、ページ内の全てのリンク(document.anchors)をチェックして、マウス前提の mouseover / mouseout 等だけが指定されているリンクに論理イベントを追加するものを作ってやれば、特に意識しなくても気配りできるようになる。
どうせマウス前提のコードをゴリゴリ書いているのだから、こういったスクリプトを一つ書いておけば実装のコストは殆どかからないだろう?


