Flexで実際の業務アプリケーションやWebサイトを構築する際に発生するトラブルに対してちょっとした工夫でアプリケーションが使いやすくなるようなTIPSをご紹介していきます。初級、中級のFlex技術者の方向けの記事となります。
例えば、ログイン画面が最初にあるアプリケーションを考えてみましょう。ユーザーとしては、アプリケーションが立ち上がった状態でキーボード入力をすると、ユーザ名などの入力欄に入力可能な状態になっていると嬉しいはずです。一見簡単に実現できそうですが、Flex/Flashアプリケーションでは少々工夫が必要になります。
Flexのコンポーネントにフォーカスを当てるには、「setFocus」メソッドを使います。
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<!-- ユーザー名入力欄 -->
<mx:TextInput id=”tiUsername” />
<!—中略 --> <mx:applicationComplete>
//ユーザー名入力欄にフォーカスをセット
tiUsername.setFocus();
</mx:applicationComplete>
</mx:Application>
しかし、これだけではTextInputにフォーカスが当たりキー入力が可能な状態にはなりません。キー入力を可能にするには、FlashのSWFがロードされている領域に「ブラウザのフォーカスが当たっている」必要があります。
通常、ユーザーがFlashの領域をクリックすることなどにより、ブラウザのフォーカスがセットされますが、ユーザーの操作がない初期状態でフォーカスをセットするには、JavaScriptを使用して明示的に行う必要があります。
<head>
<script language="JavaScript" type="text/javascript">
//Firefoxでの例
function setFocus() {
// “myapp”が、SWFが読み込まれている領域
var app = document.getElementById("myapp");
if (app) { app.focus() }
}
</head>
</script>
以上を整理してみます。
「1」の処理ですが、ブラウザの種類・バージョンによって適切な記述が微妙に異なりますので、クロスブラウザ処理を容易にするために、ライブラリを使うことにします。今回はgoogleの「base2」を使用しました。
また、「2」の処理ですが、コンポーネントに対するsetFocusの呼び出しを、例えばアプリケーションの「applicationComplete」イベントハンドラに記述することも出来ますが、アプリケーションを作成する毎記述するのは少々面倒です。Applicationクラスを継承したサブクラスを作成し、共通処理としてそこに記述するようにしましょう。
package {
import mx.core.Application;
import mx.core.UIComponent;
import mx.events.FlexEvent;
public class DefaultFocusAwareApplication extends Application {
/**
* アプリケーション起動時にフォーカスをセットする対象
*/
public var defaultFocus:UIComponent = null;
/**
* コンストラクタ
*/
public function DefaultFocusAwareApplication() {
super();
addEventListener(FlexEvent.INITIALIZE, initializeHandler);
}
/**
* Applicationのinitializeイベントハンドラ
*/ protected function initializeHandler(event:FlexEvent):void {
removeEventListener(event.type, arguments.callee);
if (defaultFocus) {
defaultFocus.addEventListener(FlexEvent.CREATION_COMPLETE, setFocusWhenTheTargetAvailable);
}
}
アプリケーションの読み込み用のHTMLには、カスタムのJavaScriptを追加する必要があるため、index.template.htmlに記述を追加します。
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<!--
Smart developers always View Source.
This application was built using Adobe Flex, an open source framework for building rich Internet applications that get delivered via the Flash Player or to desktops via Adobe AIR.
Learn more about Flex at http://flex.org
// -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>${title}</title>
<script src="AC_OETags.js" language="javascript"></script>
<!-- 追加 -->
<script src="http://base2.googlecode.com/svn/version/1.0/base2-legacy-p.js" type="text/javascript"></script>
<script src="http://base2.googlecode.com/svn/version/1.0/base2-dom-fp.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
base2.DOM.bind(document);
document.addEventListener('DOMContentLoaded', setFocus, false);
function setFocus() {
var app = document.getElementById("${application}");
if (app) { app.focus() }
}
<!-- /追加 -->
</script>
動作確認は、Internet Explorer 8, Firefox 3.0.15にて行いました。
ただ、残念ながら、Safari, Chromeでは、動作しませんでした。これらのブラウザでは、SWF領域に対して「focus()」を実行しても、フォーカスが設定されないようです。