技 巧 鍵 盤 ─ KeyNavi:キーボードを活用してホームページを快適に─    
キー割当表示[Shift-H]        
ホーム KeyNavi対応方法 [0] JavaScript@Keynavi.Netトップ [1] キーイベント処理の工夫 ・サイトマップ [Shift-S]

■ キーイベント処理の工夫

キーイベントの取得は 処理を行うハンドラ関数を定義し documentオブジェクトに登録することで可能です。

【一般的なキーイベントの処理例】

<script language="javascript"><!--

//イベント発生時に実行する関数:一般に返り値が「false」ならブラウザ側の割当て無視。//
function my_down(e){ .....; return true/false; }
function my_press(e){ .....; return true/false; }
function my_up(e){ .....; return true/false; }

//Netscape4.xでは下記が必要です。//
if(KL_NS4){
        document.captureEvents(Event.KEYDOWN);
        document.captureEvents(Event.KEYPRESS);
        document.captureEvents(Event.KEYUP);
}        

//ハンドラ関数の登録。Netscape6+,Mozillaではdocument.addEventListener使用。//
if(KL_NS6){
        document.addEventListener("keydown",my_down,true);
        document.addEventListener("keypress",my_press,true);
        document.addEventListener("keyup",my_up,true);
}else{
        document.onkeydown=my_down;
        document.onkeypress=my_press;
        document.onkeyup=my_up;
}

//ブラウザ既定のショートカットを完全に上書きするには以下。//
function kl_cancel(e){
        if(e.preventDefault) e.preventDefault();
        if(!KL_IE4) return;
        e.keyCode=0;
        e.cancelBubble=true;
        e.returnValue=false;
}
//-->
</script>

押されたキーを判定

引数「e」(イベントオブジェクト)に対し押されたキーについての情報は以下の属性で 得られます。
IE4+,Operaでは「e」は「undefined」になる。代わりに大域変数「event」を使います。

    ○キーコード
        Netscape4,6,7では「e.which」IE,Operaでは「event.keyCode」

    ○キー名(ASCII文字)
        上で得られたキーコードkcに対し「String.fromCharCode(kc)」

    ○修飾キーALT
        Netscape4では「e.modifiers&1」その他「e.altKey」

    ○修飾キーCTRL
        Netscape4では「e.modifiers&2」その他「e.ctrlKey」

    ○修飾キーShift
        Netscape4では「e.modifiers&4」その他「e.shiftKey」

ハンドラ関数の登録

キーイベントを処理するハンドラ関数は 「document.onkeydown=関数オブジェクト」等として documentオブジェクトに登録します。 Netscape4.xでは「document.captureEvents(Event.KEYDOWN)」 の実行も併せて必要です。 またNetscape6+などMozilla系ブラウザでは「addEventListener」を使えます。

問題点:キーコードが各ブラウザ、各イベント毎にバラバラ

上記方法でプログラミングする場合困った問題があります。 各キーイベントに対するキーコードはブラウザ毎に微妙に異なり、 また動作に様々な問題があります。 その中から幾つか例を挙げてみます。

keydown/up時にピリオドが文字化け (IE4-6)
IE4+では 英数字以外のキーは「keydown,keyup」時のキーコードが特殊です。 例えば「.」(ピリオド)はキーコードが190となり「3/4」みたいな文字になります。 そのためIE4+では「keypress」でキーコードを処理するのが良いです。
但しCtrlやALTが押されている場合は逆にkeydownで処理する必要があります(略)。
keypress時に英字を数字と誤判定 (Opera6)
一方Opera6(Windows版)では「keypress」時に 「A-I」キーに対するキーコードが数字の「0-9」になっています。 そのためOpera6ではkeydownで処理します。
ちなみにLinux版Opera6やOpera7ではこの問題はありません。
keypress時にShiftを解釈できない (Netscape6)
Win版NS6.0,6.1等ではkeypress時に 「Shift-F」などを押しても 「Shiftキーが押されていることを判別できません (「e.shiftKey」がfalseになる)。
これに対応するには keydown時に「Shift」が押されているか確認し それを内部変数として保持してkeypress時に反映します。

これらの問題を抽象化し ブラウザ間差異、イベント間差異を意識せずに 簡単にキーイベントを処理できる仕組みを考案しました。


KeyNaviのキーイベント処理

キーイベントの処理はIE4+,NS4,NS6+,Opera,Mozillaで可能です。 KeyNaviライブラリを使うと それらに対応したスクリプトを単一のコードでラクに書けます。

拡張キー名:knx (KeyName eXtended)

キーイベントを扱う時に処理すべきパラメータは 修飾キー(ALT,Ctrl,Shift)とキーコード(或いはキー名)の4つにもなります。 変数が多いと扱い難いのでまとめてしまいます。

「J」(単独)→ knx='J'
「ALT-J → knx='aJ'
「Ctrl-J」→knx='cJ'
「Shift-J」→knx='sJ'
「Ctrl-ALT-J] →knx='acJ'
「Ctrl-ALT-Shift-J」→knx='acsJ'
修飾キー(a,c,s)が複数ある場合はアルファベット順にします。

こうすると1つのパラメータ「knx」でキー入力を扱えます。

ショートカット用配列:KL_KEY2XXX

上のknxを用いてショートカットを簡単に実装できます。

【ショートカット用配列:KL_KEY2...】

KL_KEY2URL [knx]='JumpしたいURL名'
KL_KEY2CLK [knx]= click()を実行するオブジェクト (or ID)
KL_KEY2FCS [knx]= focus()を実行するオブジェクト (or ID)
KL_KEY2FNC [knx]= 関数オブジェクト
KL_KEY2NAME[knx]= 移動先のアンカー名 (or その配列=連続入力で巡回移動)

たとえば「Shift-Y」が押された時に「YahooJapan!」に移動するには
「KL_KEY2URL["sY"]="http://www.yahoo.co.jp"」とすればOKです。

上記コマンドを実行後「Shift-Y」を入力してみて下さい。

HTMLのみでショートカット指定1:id,name値で設定

上の例ではJavaScriptの記述が必要でしたがHTMLのみでも ショートカットを作れます。 リンクやFormボタンに対し 特殊なid,name値を与えると ショートカットとして解釈されます。 例えば 「<a href="http://www.yahoo.co.jp" id="kl_focus_sY">Yahoo!</a>」 とすると「Shift-Y」入力でこのリンクにフォーカスします。 「id="kl_click_sY"」とするとクリックを実行するのでYahoo!のページに 移動できます。
id,name値で「kl_focus」「kl_click」で始まるものを登録。 オプション定数を書き替えれば異なるものにも出来ます。

HTMLのみでショートカット指定2:リンクラベル

リンクやボタンのラベルに表示されている文字列でショートカットを作れます。 オプション指定で「KL_KEY2FCS_MODE="initial_shift";」とすると 「Shift-Y」入力で「Y」で始まるリンク、例えば先のYahoo!などにFocusします。
この方法は英文ページでは強力です。 アプリケーションサーバZopeでの利用 ではこの方法を使っています。

オプション値が「[]_shift」だと(デフォルト)、 「[Y]ahooJapan!」の括弧内の「Y」を解釈して同様に動作します。 「Yahoo[J]apan!」なら「J」になります。

この方法では頭文字、括弧「()」「[]」を使ったリンクに対応しています。 内部関数「拡張キー名=kl_elem_key(要素,モード名)」を上書き定義すると ショートカット指定アルゴリズムを任意にカスタマイズできます。

KeyNavi拡張用関数:kl_keyfunc_ex(stat)

単純なショートカットは先の例で作れますが 様々なキーイベントに対し凝った処理をしたい場合は関数を定義します。
この関数を使うと先述のブラウザの違いや各キーイベントの特殊性を考えずに コーディングできます。

引数「stat」にはキーイベントに関する様々な情報が格納されています。

【カスタマイズ用関数:kl_keyfunc_ex(stat)】

//--------------------------------
//stat:イベント状態を表す引数
//stat["kc"]=キーコード(数字)
//stat["kn"]=キー名
//stat["knx"]=拡張キー名 (先述)
//stat["md"]=修飾子の情報 (md["alt"]/md["ctrl"]/md["shift"]が真偽値)
//stat["action"]=キー入力時の動作(keydown/keypress/keyupの何れか)
//stat["e"]=イベントオブジェクト (IE4+,Operaではevent)
//--------------------------------
function kl_keyfunc_ex(stat){
        .............
        return true;   //該当キーイベントを他の関数でも処理する場合
        return false;  //他の機能は呼ばない場合
}

先述の「Shift-Y」入力でYahoo!に飛ぶには以下の様にします。

【kl_keyfunc_ex()の利用例:Copy&Paste】

<script language="javascript" src="http://www.keynavi.net/files/keynavi_ja.js"></script>

<script language="javascript"><!--
function kl_keyfunc_ex(stat){
        if(stat["knx"]=="sY") location="http://www.yahoo.co.jp";
        return false;
}
//-->
</script>

上の実行ボタンを押した後「Shift-Y」を入力してみて下さい。 「YahooJapan!」に移動します。

この例では各キーイベントに対してキー状態をステータスバーに表示します。 例えば「Ctrl-U」「ALT-U」「Shift-U」など色々組合わせて押してみて下さい。

「Ctrl」「ALT」を押すときはブラウザ既定のショートカットと 重なる場合があるので注意。 例えば「Ctrl-N」とすると新しいウィンドウが開きます。 「return false」するとこれらを動作させないことができます。

その他の一般拡張用関数

3種類のキーイベント「keydown/keypress/keyup」やその他のイベント に合わせて以下のような拡張用関数が用意されています。
KeyNaviでは「onkeydown/ onkeypress/ onkeyup/ onload/ onmousedown/ onresize」 に対しイベントハンドラを登録しています。 これらのイベントに対してこの方法が使えます。

イベントハンドラの登録を 一般的なキーイベントの処理例 (このページ内)のように「べた書き」するとメンドウなので 以下の関数の利用をお勧めします。

【各種拡張用関数】

// keydown/press/up全ての場合で呼ばれる関数 //
function kl_keyfunc0_ex(stat){ return true; }


// それぞれkeydown/keypress/keyup時に呼ばれる原始的な関数 //
// (document.xxxに登録するものと同等) //
function kl_onkeydown_ex(e) { return true; }
function kl_onkeypress_ex(e){ return true; }
function kl_onkeyup_ex(e)   { return true; }


// onLoad時に呼ばれる //
function kl_onload_ex(e)     { return true; }


// ウィンドウサイズ変更時 //
function kl_onresize_ex(e)   { return true; }


// マウスボタンが押された時 //
function kl_onmousedown_ex(e){ return true; }


// KeyNaviセットアップ関数実行時 //
function kl_setup_ex(e){ return true; }

kl_setup_ex(): 上のリスト内の「kl_setup_ex()」はKeyNavi起動時に実行されます。 外部スクリプト「keynavi_ja.js」の指定の前に書く必要があります。 この関数は内部定数の変更などに良く使われます。

これらの関数は定義するだけで勝手に呼ばれます。 ハンドラ登録は不要です。 これを利用したサンプルはキーやマウスが押されたことを確認したい

ハンドラ関数を主体的に登録したい場合は 「kl_addhandler(o,mode,func)」 を使うことも出来ます。

このサンプルはマウス位置取得:kl_mousex,y()

特に上のリストにあるように KeyNaviでハンドラ関数を登録しているイベントについてはオブジェクト引数「o」 を略した「kl_addhandler_ex(mode,func)」を使えます。 この場合もブラウザ毎の分岐処理は不要で 一行でハンドラ登録できます。

使用例についてはレイヤーをウィンドウ内の中心位置に固定 の終わりのほうを見てください。




【JavaScript@Keynavi.Net : キーイベント処理編 】
「Ctrl-矢印」でフォーカスを上下左右に移動できます。

  - キーやマウスが押されたことを確認したい
  - キーイベント処理の工夫

トップへ戻る [1]
ホーム KeyNavi対応方法 [0] JavaScript@Keynavi.Netトップ [1] キーイベント処理の工夫 ・サイトマップ [Shift-S]
キー割当表示[Shift-H] ─ KeyNavi Project 2003 ─