Adobe AIR と ExtJS の入門(2) - エフェクトとイベントを使う
クジラ飛行机です。前回から、Adobe AIR (JavaScript) でよく使われるJavaScriptのライブラリ、ExtJS を紹介しています。ExtJS を使うと、リッチなUIを使った Web アプリケーションを比較的簡単に作成できます。メッセージボックスなどもいちいちカッコよく、グリッドやパネルのレイアウトも手軽に作成できます。また、ExtJS には AIR との連携を考慮されたライブラリも多くあります。
今まで、ExtJS が気になっていた方に向けた入門講座になっています。JavaScriptをそれほど熟知していない方でも気軽に読める内容です。ぜひ、読んでみてください。
Hello, Worldのおさらい
前回、Aptana Studio を利用して、Hello, World を作ってみました。再度、おさらいとして、Hello, World を作ってみたいと思います。なお、この Hello, Wolrd はこれから作るプロジェクトの雛型としても利用します。Aptana に AIR プラグインを導入したものとして話を進めていきますので、導入していない方は、インストールしてみてください。
手順(1) プロジェクトの作成
以下の操作に沿って、Test2 プロジェクトを作ってみてください。
- (1) Aptanaのファイルメニューから、新規プロジェクトをクリックします。(File - New - Projectと辿ります。)
- (2) どんなプロジェクトを作成するか選択画面が出るので、AIR Project を選択します。
- (3) Projectの作成画面が出るので、適当に、Test2 という名前をつけて、[Next]ボタンをクリックしていきます。(AIR の設定では、画面のサイズなども指定できますが、適当に[Next]をクリックします。)
- (4) ライブラリの選択画面が出たら、ExtJS 2.0.2 にチェックを入れます。(以前のAptanaでは選択できませんでしたが、最新版にアップデートすると選択できるようになります。)
以上の操作で、AIR + ExtJS2.0.2を使う準備が整いました。作成されたプロジェクトを見てみると、lib フォルダの中に、ext のライブラリがコピーされていることが分かるでしょう。
手順(2) Test2.html を書き換える
プロジェクトが作成出来たら、プログラムを作っていきます。Aptana でプロジェクトを作ると、AIR の雛型が自動生成されますが、ここでは、Test2.html を以下のように書き換えます。
<html><head>
<!-- ExtJS を使う上での基本的なライブラリの取り込み-->
<script type="text/javascript" src="lib/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="lib/ext/ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css"/>
</head><body>
<script type="text/javascript">
// ここにプログラムを記述
Ext.onReady(function(){
Ext.MessageBox.alert("Test2", "Hello, World!");
});
</script>
</body></html>
これを、実行してみると、以下のような Hello, World とダイアログに表示するプログラムが完成しました。
このプログラムは、前回作ったものと、ほぼ同じですので、そのポイントを簡単にをまとめると、次のようになるでしょう。
- ExtJSを使うためには、ライブラリの取り込みを行う必要があります。ここでは、head タグの中にある取り込み script タグの宣言で取り込んでいます。
- ExtJSでは、基本的な動作を行う Ajax ライブラリを、prototype.js や jQuery、yui から選択できるようになっています。ここでは、ExtJS 標準のもの「ext-base.js」を選択しています。
- ExtJSのメインライブラリの取り込みが「ext-all-debug.js」です。これは、デバッグ版なので、本番にリリースするときには、「ext-all.js」を取り込むようにします。
Ext.onReady() に初期化コードを記述する
ExtJS を使うための準備が整いましたので、これから、ExtJS を使っていろいろなプログラムを作っていきます。
さて、Ajax のライブラリでよく使われる JavaScript の書き方で、引数に無名関数のプログラムを与えるというものがあります。これは、上記の、Hello, World にも登場しています。これが分からないと、ExtJS を使いこなせないので、簡単に捕捉しておきます。
Hello,World のメインプログラムだけを取り出すと、以下のようなものになっています。よくみると、Ext.onReady() メソッドに、function(){..} という関数の定義を与えるという形になっているのです。
<script type="text/javascript">
Ext.onReady(function(){
Ext.MessageBox.alert("Test2", "Hello, World!");
});
</script>
これは、以下のようなプログラムを書くのと同じ意味になります。C言語風に言うと、コールバック関数を与えるというニュアンスに近いでしょうか。とにかく、ExtJS で、プログラムの初期化を行うメソッド「Ext.onReady」にプログラムの初期化を行う関数を指定しています。
<script type="text/javascript">
// 関数 sayHello の定義
function sayHello() {
Ext.MessageBox.alert("Test2", "Hello, World!");
}
// ExtJS の初期化関数を指定
Ext.onReady( sayHello );
</script>
そして、Ajax のライブラリでは、このように、メソッドの引数として、関数を与えるという場面が多く出てくるのです。そのため、いちいち、関数を定義して、これを引数として与えるという方法よりも、より簡潔で柔軟性に富んだ、無名関数を指定する方法(冒頭の Hello, World のような書き方)が利用されることが多いのです。
参考までに、関数定義を、一度、変数 f に代入し、これを、Ext.onReady の引数に与えるという書き方も見てみましょう。(このとき、変数 f には、関数オブジェクトが代入されています。)これも、冒頭の Hello, World と同じ意味になります。
<script type="text/javascript">
var f = function () {
Ext.MessageBox.alert("Test2", "Hello, World!");
};
Ext.onReady( f );
</script>
とにかく、このように、Ext.onReady に初期化を行うコードを記述することができるということを覚えておきましょう。
簡単なエフェクトを使おう
次に、HTML ドキュメントを書き換える方法を学びましょう。DOMの要素を取得して書き換える、あるいは、update()関数を操作します。これは、Ajax の最も基本的な操作の例です。以下は、id に message_div と書かれている DIV タグの内容を、Hello に書き換える例です。
<html><head>
<!-- ExtJS を使う上での基本的なライブラリの取り込み-->
<script type="text/javascript" src="lib/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="lib/ext/ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css"/>
</head><body>
<!-- 以下の div を書き換える -->
<div id="message_div">***</div>
<script type="text/javascript">
var e = Ext.get("message_div"); // --- (*1) Element オブジェクトを得る
e.update("<p>Hello!</p>");// --- (*2) テキストを書き換え
</script>
</body></html>
プログラム中の (*1) で、message_div という Element オブジェクトを取得します。(*2)で、その オブジェクトのテキストを書き換えます。
Ext.get() メソッドを利用することで、任意の id に対応した Element オブジェクトを取得することができます。ExtJS の Element オブジェクトには、いろいろなメソッドが用意されており、この Element オブジェクトを操作することで、さまざまなエフェクトを利用することができます。
例えば、任意の要素を一瞬光らせる highlight エフェクトを利用してみます。上記のスクリプト部分を次のように書き換えます。
<script type="text/javascript">
var e = Ext.get("message_div"); // Element オブジェクトを取得
e.update("Hello!"); // テキストを書き換え
e.highlight(); // 一瞬光らせる
</script>
上記のプログラムを実行すると、テキストを書き換えた後、highlight() エフェクトが実行され、message_div の div タグを光らせるエフェクトを見ることができます。他にも、文字を上から下へとスライドさせる、slideIn() エフェクトも使えます。
var e = Ext.get("message_div");
e.update("Hello!");
e.slideIn();
手軽に利用できるエフェクトには、次のものが用意されています。(これは、一部を抜粋したものです。)
| highlight | 一瞬光らせる |
| slideIn | 上から下へスライドさせて、表示させる |
| slideOut | 下から上へスライドさせて、表示を消す |
| puff | 広がって消える |
| frame | 要素の枠が外側へ広がって消える |
| ghost | 透明になりながら下がって消える |
| switchOff | 電気を切るように一瞬点滅して消える |
しかも、これらのエフェクトを連続で組み合わせることができるのです。エフェクトの組み合わせ方は、次の通り、ドットで区切って数珠つなぎにメソッドを足していくだけです。以下の例は、光らせて、透明にして、また出てくるというエフェクトを実行するものです。
var e = Ext.get("message_div");
e.highlight().ghost().slideIn();
このような書き方をメソッドチェーンと言います。仕組みとしては、メソッドを呼ぶと自分自身(this つまり、Element 要素)を返す仕組みになって、また、別のエフェクトを呼ぶことができるようになっているのです。
この仕組みによって、独特な Ajax 風なエフェクトを手軽に表現できます。これにより、ユーザーの注意を引くことができるかもしれません。
イベントを利用しよう
次に、ExtJS で用意されているイベントを利用してみます。イベントを設定するには、Ext.get() メソッドで取得した Element オブジェクトに対して、on() メソッドでイベントを設定します。
はじめに簡単な例として、ボタンをクリックしたら、メッセージを表示するという簡単なプログラムを作ってみます。
<html><head>
<!-- ExtJS を使う上での基本的なライブラリの取り込み-->
<script type="text/javascript" src="lib/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="lib/ext/ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css"/>
</head><body>
<!-- 以下の div を書き換える -->
<div id="a_btn">[BUTTON]</div>
<script type="text/javascript">
var e = Ext.get("a_btn");
e.on("click", function(){
alert("Hello!");
});
</script>
</body></html>
ポイントとなるのが、まさにイベントを設定している部分「e.on("click", function(){..})」です。また、関数を引数に設定するというスタイルが出てきました。このように、ExtJS では、イベントを設定する場合には、Element の on() メソッドにイベントの名前と、実行する関数を指定するようになっているのです。
Adobe AIR の注意~セキュリティの制約を理解する
AIR では、イベント処理の中から、Ext.MessageBox を使おうとしても「使えない」という現象が起きてしまいます。次のコードを実行してみてください。
<html><head>
<!-- ExtJS を使う上での基本的なライブラリの取り込み-->
<script type="text/javascript" src="lib/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="lib/ext/ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css"/>
</head><body>
<div id="a_btn">[BUTTON]</div>
<script type="text/javascript">
var e = Ext.get("a_btn");
e.on("click", function(){
Ext.MessageBox.alert("test","Hello!");
});
</script>
</body></html>
エラーを詳しく見ると、「"Error: Adobe AIR runtime security violation for JavaScript code in the application security sandbox (eval)"」というメッセージが出ていると思います。
つまり、デフォルトの AIR アプリケーションでは、普通に eval() メソッドが使えないのです。eval() が使えないということは、Ajax ライブラリの大半が動かないということです。これは、Adobe がセキュリティに配慮した結果なのですが、Ajax のライブリが使えないというのは、実に困ったことです。
しかし、そこは、AIR です。しっかり抜け道が用意されています。AIR アプリケーションには、Application sandbox と Non-application sandbox の2種類のセキュリティが用意されています。Application sandbox では、ファイルアクセスやその他の AIR ならではの機能が使えますが、JavaScript の eval() などのダイナミックな機能な使えなくなります。それに対し、Non-application sandbox では、よりHTMLのセキュリティ制約が強まり、その結果、AIR ならではの機能が使えなくなるのですが、eval() は従来通り使えるというものなのです。
つまり、セキュリティが厳しいモード(Non-application)では、「すべての JavaScript が使えるけど、AIR の機能は使えないよ」、セキュリティが弱いモード(Application)では、「AIR の機能は使えるけど、JavaScriptのダイナミックな機能は使えないよ」ということなのです。
AIR で、Non-application sandbox を使うにはどうすれば良いのかというと、iframe タグで、外部のHTMLを埋め込む時に、セキュリティがどの Sandbox に属するのかを宣言するようにします。具体的には次のようになります。
以下のプログラムは、ボタンをクリックしたときに、メッセージボックスを表示するという簡単なものです。
file:mainapp.html — Application Sandbox で実行される
<html><body>
<iframe id="UI"
src="nonappbox.html"
sandboxRoot="http://example.com/"
documentRoot="app:/"
width="300" height="300">
</iframe>
</body></html>
file:nonappbox.html — Non-application Sandbox で実行される
<html><head>
<!-- ExtJS を使う上での基本的なライブラリの取り込み-->
<script type="text/javascript" src="lib/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="lib/ext/ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css"/>
</head><body>
<input type="button" id="a_btn" value="say"/>
<script type="text/javascript">
Ext.get("a_btn").on("click", function(){
Ext.MessageBox.alert("Test","Hello!");
});
</script>
</body></html>
ExtJS は内部の処理において、eval() メソッドを利用ているため、セキュリティ的に、Non-application sandbox で実行する必要があるのです。
まとめ
今回も、簡単に Adobe AIR + ExtJS でエフェクトとイベント処理の使い方を紹介しました。メッセージボックスの使い方を復習し、各種エフェクトの効果と使い方を覚えました。また、イベント処理についても紹介しましたが、標準の状態(Application sandbox)では、イベントと組み合わせることで、AIR のセキュリティに引っ掛かるということも解説しました。AIR と Ajax のライブラリを組み合わせる場合には、こうしたセキュリティの制約を理解した上で利用しなくてはなりません。
それでは、次回は、以下の予定でお届けするつもりです。
- イベント処理の復習
- もっと複雑なメッセージボックスを使う
- テンプレートエンジンの使用
お楽しみに。
このサイトについて
TrackBack URL :





