Flexで実際の業務アプリケーションやWebサイトを構築する際にキーボード周りの実装でトラブルが発生することがあります。ちょっとした工夫でトラブルを回避し、アプリケーションが使いやすくなるようなTIPSを紹介します。この記事は初級、中級のFlex技術者の向けです。
Flexアプリケーション、特に業務用途では、要件にキーボードショートカットが含まれることが多くなります。一般的なアプリケーションでは、キーボードショートカットは当たり前のように定義されていますし、良く使われる機能に対してキーボードショートカットを定義することは、ユーザビリティの向上や業務効率の改善に繋がるため、求められることの多い機能であるように思います。
(良く耳にするのは、ファンクションキー(F1~F10)に対して、特定の操作を割り当てたいという要求)
ところが、Flexアプリケーションでは、全てのキーボードショートカットを使用できる訳ではありません。
これは、Flexアプリケーションがブラウザ上で動作することによる制約です。
Flexで使用できるキーボードショートカットが一覧になっているものを探したのですが、見当たらなかったため、今回一覧表をブラウザ毎に作成しました。Flexアプリケーションの仕様の検討の際などに役立てて頂ければ幸いです。
また、キーボードショートカットが使えるかどうかの判定に使えるサンプルも併せて作成しました。
Flexでキーボードショートカットを実装する方法は最後に紹介しますので参考にして下さい。
以下のような制約が存在します。
単体で動作するAIRアプリにはこの制限はありませんが、ブラウザ上で動作するFlexアプリケーションの場合、ブラウザにショートカットキーのイベントがインターセプトされてしまいます。その結果、Flexアプリ側ではそのキーのイベントを検出することができません。
JavaScriptを用いて、ブラウザに一旦受け付けられたキー入力を、独自にFlash側に送るという実装も可能ですが、キーによっては完全に動作しないこともあります。また、実装や仕組みが煩雑になることや保守性の低下などの点からあまりお勧めできません。
OSのショートカットキーは、OSにショートカットキーのイベントがインターセプトされ検出できない、あるいは、検出はできるがOSのデフォルトの挙動が実行され、結果としてFlashからキーフォーカスが外れるため、Flashでの使用は困難です(例: Windowsキー)。
また、Windows環境においては、Alt+Tabなど、Altキーと他の何かのキーの組み合わせは検出できません。これは、Altキーがアプリケーションの「アクセラレータキー」として機能するためです(例: メニューを開く)
FlashPlayerの制約で、そもそも押されたことを検知出来ないキーが存在します (F10キー)。
参照ページ(Flash CS3 ドキュメンテーション キーボードのキーとキーコードの値)
それでは実際の実装例を紹介します。
実際の動作確認はこちらからご利用ください。
キーボードイベントを監視・取得して、押されたキーの情報を下のテキストエリアに表示するサンプルです。使いたいキーボードショートカットが使えるかどうか、確かめることが出来ます。
ソースコードは、右クリック→「view source」で参照して下さい。
キーボードショートカットについて駆け足で紹介しましたが、いかがでしたでしょうか?
ところで、本編とは直接関係ありませんが、タブキーによるフォーカス関連で便利なTipsを一つご紹介します。
Flash Playerには「SeamlessTabbing」というプロパティがあり、これを「false」に設定することで、FlexアプリでTABキーを押し続けた際に、ブラウザのアドレスバーへ移動せずFlexアプリ内だけでフォーカス移動が完結するようになります。
一般的なFlexアプリケーションでは、ブラウザのアドレスバーへフォーカスが移動しない方が好都合のことが多いと思われますので、このプロパティは「false」に設定すると良いでしょう。
このプロパティのデフォルト値は「true」なので、明示的に設定しない限り、Flexアプリケーション内でTABキーを押し続けた際には、Flexアプリからブラウザのアドレスバーへフォーカスが「シームレスに」移動するという挙動になります。
「SeamlessTabbing」プロパティの指定は、SWFをロードするHTMLファイルで行います。Flexでは、プロジェクト内の「/html-template/index.template.html」に設定を追加するとよいでしょう。
<body scroll='no'>
<script language="JavaScript" type="text/javascript">
<!--
AC_FL_RunContent(
"src", "${swf}",
"width", "${width}",
"height", "${height}",
"align", "middle",
"id", "${application}",
"quality", "high",
"bgcolor", "${bgcolor}",
"name", "${application}",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer",
"SeamlessTabbing", "false"
);
// -->
</script>
<noscript>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="${application}" width="${width}" height="${height}"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="${swf}.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="${bgcolor}" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="${swf}.swf" quality="high" bgcolor="${bgcolor}"
width="${width}" height="${height}" name="${application}" align="middle"
play="true"
loop="false"
quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer"
SeamlessTabbing="false">
</embed>
</object>
</noscript>
</body>