厄介なキーイベントの処理もDojoなら楽勝!

DOMイベントやキーイベントは、ブラウザ間で特に差異が大きい部分だ。例えば、「ページ内でCtrl+Sキーを押されたら保存を行う」と言った処理を考えてみよう。それには、以下のような処理が必要だ。

  • CtrlキーとSが同時に押されていることを検知する
  • Ctrl+Sが押されたイベントをブラウザに伝播させない (Webページの保存ダイアログなどが開いてしまう)

このどちらも、ブラウザごとにかなり異なるAPIとなってしまっているため、どのブラウザでも同様に動作するよう実装するのはかなりの困難を伴う。これに加え、ファンクションキーなどにも対応しなければならないとしたら、キーコードがブラウザごとに異なっていたりと、さらに状況は複雑だ。 こうした問題を、Dojoを使用すれば簡単に解決できる。

以下のサンプルは、テキストフィールドにフォーカスが当たった状態でキーを入力すると、下にその情報が表示されるというものだ。CtrlキーやShiftキーが同時に押されてことや、TABキーやファンクションキーの情報も適切に表示される。

押されたキーの情報を表示するサンプル

ソースコードは以下の通りだ。

 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
 <script src="../js/dojo/dojo.js" djConfig="isDebug:true"></script>
 <script type="text/javascript">
   dojo.addOnLoad(init);

   function init() {
     dojo.connect(dojo.byId("input"), "onkeypress", function(e) {
       // (1) イベントオブジェクトのkeyCharに、押されたキーが格納されている
       var keyChar = e.keyChar;
       // keyCharが空の場合は、特殊なキー
       if (keyChar == "") {
         // (2) dojo.keysの定数と比較すればキーの種類が判明する
         for (var k in dojo.keys) {
           if (dojo.keys[k] == e.keyCode) {
             keyChar = k;
           }
         }
       }
       var msg = "<br/>押されたキー:" + keyChar;
       msg += "<br/>Ctrlキーが押されているか:" + e.ctrlKey;
       msg += "<br/>Shiftキーが押されているか:" + e.shiftKey;
       msg += "<br/>Altキーが押されているか:" + e.altKey;

       dojo.byId("output").innerHTML = msg;
       // (3) イベントにおけるデフォルトの振る舞いを止め、
       //     イベントの伝播を阻止する
       e.preventDefault();
       e.stopPropagation();
     })
   }
 </script>
 </head>
 <body>
   キーを入力してください:<input id="input" type="text">
   <span id="output"></span>
 </body>
 </html>

(1) dojo.connect()を使用してonkeypressイベントを捕捉すると、イベントオブジェクト内の「keyChar」というプロパティに、押されたキーが文字列で格納される。

(2) keyCharが空の場合は、Tabやファンクションキー、Caps Lockなどの特殊なキーだ。こうしたキーは、keyCodeプロパティの値をdojo.keysというオブジェクト内の定数と比較すれば、キーの種別が判明する。ここでは、押されたキーの種別を確認するために、dojo.keysの中身をループしてキーコードと比較している。通常は以下のように、定数値とキーコードを直接比較することになるだろう。

 // 押されたキーがEscapeかどうかを判定する
 if (e.keyCode == dojo.keys.ESCAPE) {
   …
 }

また、dojo.keysは以下のように定義されている。

 dojo.keys = {
   BACKSPACE: 8,
   TAB: 9,
   CLEAR: 12,
   ENTER: 13,
   SHIFT: 16,
   …
 };

完全な一覧を見たければ、dojo/_base/event.jsの中身を確認するか、こちらのページ 一覧が載っているので参照していただきたい。

(3) キーイベントが持つデフォルトの振る舞い (Ctrl+Nで新規ウィンドウ、など) を停止し、イベントがテキストフィールドの親に伝播しないようにする。こうしたメソッドは、ブラウザ間 (特にIE) でAPIが異なるが、Dojoがうまく隠ぺいしている。

このように、Dojoを使用すればクロスブラウザで動作するショートカットキーなども簡単に作成できる。