Flash CS3 ドキュメンテーション |
|||
| ActionScript 3.0 のプログラミング > External API の使用 > 例 : Web ページコンテナに対する External API の使用 | |||
このサンプルアプリケーションでは、ユーザーが自分自身とチャットできる Instant Messaging アプリケーションの場合に、Web ブラウザ内で ActionScript と JavaScript が通信するための方法を示しています (アプリケーション名: Introvert IM)。メッセージは External API を使用して、Web ページ内の HTML 形式と SWF インターフェイスとの間で送信されます。この例で示す方法では、次のことを行います。
このサンプルのアプリケーションファイルを入手するには、www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。Introvert IM アプリケーションのファイルは、Samples/IntrovertIM_HTML フォルダにあります。アプリケーションは、次のファイルで構成されています。
|
ファイル |
説明 |
|---|---|
|
IntrovertIMApp.fla または IntrovertIMApp.mxml |
Flash (FLA) または Flex (MXML) のメインアプリケーションファイル |
|
com/example/programmingas3/introvertIM/IMManager.as |
ActionScript とコンテナとの間の通信を確立および管理するクラス。 |
|
com/example/programmingas3/introvertIM/IMMessageEvent.as |
コンテナからメッセージを受信したときに IMManager クラスから送出されるカスタムイベントタイプ。 |
|
com/example/programmingas3/introvertIM/IMStatus.as |
アプリケーションで選択可能な、さまざまな "availability" ステータス値を値が表している列挙。 |
|
html-flash/IntrovertIMApp.html または html-template/index.template.html |
Flash アプリケーションの HTML ページ (html-flash/IntrovertIMApp.html) または Adobe Flex アプリケーションのコンテナ HTML ページ作成に使用するテンプレート (html-template/index.template.html).このファイルには、アプリケーションのコンテナ部分を構成するすべての JavaScript 関数が格納されています。 |
External API の最も一般的な用途の 1 つは、ActionScript アプリケーションと Web ブラウザとの通信です。External API を使用すると、ActionScript メソッドから JavaScript コードへの呼び出し、および JavaScript コードから ActionScript メソッドへの呼び出しを実現できます。ブラウザの仕組みは複雑であり、また、ブラウザ内部で実行されるページレンダリング処理が不明であることから、HTML ページ上の JavaScript コードが最初に実行される前に SWF ドキュメントのコールバックを登録できる保証はありません。したがって、JavaScript から SWF ドキュメントの関数を呼び出す前に、SWF ドキュメント側の接続受け付け準備ができたことを通知するために、必ず SWF ドキュメントから HTML ページへの呼び出しを実行してください。
たとえば、IMManager クラスで実行される一連の手順によって、ブラウザの通信準備ができ、SWF ファイルを通信で使用できることが、Introvert IM で判定されます。ブラウザの通信準備ができたことを判定する最初の手順は、次のように IMManager コンストラクタで実行されます。
public function IMManager(initialStatus:IMStatus)
{
_status = initialStatus;
// コンテナで External API を使用できることを確認する
if (ExternalInterface.available)
{
try
{
// ここで isContainerReady() メソッドを呼び出し、そのメソッドが
// コンテナを呼び出すことにより、Flash Player がロード済みでコンテナが
// SWF からの呼び出しを受信可能なことを確認する
var containerReady:Boolean = isContainerReady();
if (containerReady)
{
// コンテナが準備できている場合は、SWF の関数を登録する
setupCallbacks();
}
else
{
// コンテナの準備ができていない場合は、Timer を設定して
// 100ms 間隔でコンテナを呼び出す。コンテナの準備ができたとの応答があれば、
// タイマーを停止する
var readyTimer:Timer = new Timer(100);
readyTimer.addEventListener(TimerEvent.TIMER, timerHandler);
readyTimer.start();
}
}
...
}
else
{
trace("このコンテナでは External インターフェイスを使用できません。");
}
}
最初に、ExternalInterface.available プロパティを使用して External API が現在のコンテナで利用可能かどうかが確認されます。利用可能であれば、通信の設定手順が開始されます。外部アプリケーションと通信しようとするとセキュリティ例外やその他のエラーが発生することがあるため、コードは try ブロックでラップされています (簡単にするため、対応する catch ブロックは省略されています)。
次に、ここに示すように isContainerReady() メソッドが呼び出されます。
private function isContainerReady():Boolean
{
var result:Boolean = ExternalInterface.call("isReady");
return result;
}
isContainerReady() メソッドは、ExternalInterface.call() メソッドを使用して次のように JavaScript 関数 isReady() を呼び出します。
ActionScript で呼び出される<script language="JavaScript">
<!--
// ------- プライベート変数 -------
var jsReady = false;
...
// ------- の関数 -------
// ページが初期化されて JavaScript が利用可能になっているかどうかを確認するために呼び出す
function isReady()
{
return jsReady;
}
...
// <body> タグの onload イベントから呼び出される
function pageInit()
{
// JavaScript の準備ができたことを記録する
jsReady = true;
}
...
//-->
</script>
isReady() 関数は、単純に jsReady 変数の値を返します。この変数の初期値は false です。Web ページの onload イベントがトリガされると、変数の値が true に変化します。つまり、ページのロード前に ActionScript から isReady() 関数が呼び出されると、JavaScript から ExternalInterface.call("isReady") に false が返され、その結果 ActionScript isContainerReady() メソッドから false が返されます。ページがロードされると、JavaScript isReady() 関数から true が返されるため、ActionScript isContainerReady() メソッドからも true が返されます。
IMManager コンストラクタでは、コンテナの準備状態に応じて 2 つのことが行われます。isContainerReady() から true が返された場合は、コードから単純に setupCallbacks() メソッドが呼び出されて、JavaScript での通信の設定手順が完了します。一方、isContainerReady() から false が返された場合、手順は実質的に保留状態になります。Timer オブジェクトが作成され、次のように 100 ミリ秒間隔で timerHandler() メソッドを呼び出すよう指示されます。
private function timerHandler(event:TimerEvent):void
{
// コンテナの準備ができているかどうかを確認する
var isReady:Boolean = isContainerReady();
if (isReady)
{
// コンテナの準備ができている場合は何も確認する必要がないため、
// タイマーを停止する
Timer(event.target).stop();
// コンテナからの呼び出しが可能な ActionScript メソッドを
// 設定する
setupCallbacks();
}
}
timerHandler() メソッドが呼び出されるたびに、isContainerReady() メソッドの結果が再確認されます。コンテナが初期化されると、このメソッドから true が返されます。次に、コードでは Timer を停止して setupCallbacks() メソッドを呼び出し、ブラウザの通信の設定手順を終了します。
上記の例で示したように、ブラウザの準備ができたことがコードで判定されると、setupCallbacks() メソッドが呼び出されます。このメソッドでは、次のように JavaScript からの呼び出しを受信するよう ActionScript が準備されます。
private function setupCallbacks():void
{
// SWF クライアント関数をコンテナに登録する
ExternalInterface.addCallback("newMessage", newMessage);
ExternalInterface.addCallback("getStatus", getStatus);
// SWF の呼び出し準備ができたことをコンテナに通知する
ExternalInterface.call("setSWFIsReady");
}
setCallBacks() メソッドは、ExternalInterface.addCallback() を呼び出して JavaScript から呼び出し可能な 2 つのメソッドを登録することにより、コンテナとの通信準備のタスクを終了します。このコードでは、ActionScript のメソッド名と同じ名前が第 1 パラメータになっています。JavaScript ("newMessage" および "getStatus") は、この名前によってメソッドを認識します (この場合、異なる名前を使用することに意味がないため、同じ名前を再利用しました)。最後に、ExternalInterface.call() メソッドを使用して JavaScript 関数 setSWFIsReady() が呼び出され、ActionScript 関数の登録されたコンテナが通知されます。
Introvert IM アプリケーションは、コンテナページでの JavaScript 関数の呼び出しに関するさまざまな例を示しています。最も単純な場合 (setupCallbacks() メソッドの例) には、パラメータを渡したり、返される値を受け取ることなく、JavaScript 関数 setSWFIsReady() が呼び出されます。
ExternalInterface.call("setSWFIsReady");
isContainerReady() メソッドの別の例では、ActionScript から isReady() 関数が呼び出され、それに対する応答としてブール値を受け取ります。
var result:Boolean = ExternalInterface.call("isReady");
External API を使用して JavaScript 関数にパラメータを渡すこともできます。たとえば、IMManager クラスの sendMessage() メソッドについて考えてみます。このメソッドは、ユーザーが自分の "交信パートナー" に新しいメッセージを送信するときに呼び出されます。
public function sendMessage(message:String):void
{
ExternalInterface.call("newMessage", message);
}
ここでも、指定された JavaScript 関数が ExternalInterface.call() を使用して呼び出され、ブラウザに新しいメッセージが通知されます。また、メッセージ自身は ExternalInterface.call() の追加パラメータとして渡され、結果的に JavaScript 関数 newMessage() のパラメータとして渡されます。
通信は双方向形式でサポートされ、Introvert IM アプリケーションも例外ではありません。Flash Player IM クライアントがメッセージ送信のために JavaScript を呼び出すだけでなく、HTML フォームも JavaScript コードを呼び出して、メッセージを SWF ファイルに送信したり、SWF ファイルに情報を問い合わせます。たとえば、接続が完了し、通信準備ができたことを SWF ファイルがコンテナに通知する場合、ブラウザが最初に行うことは、IMManager クラスの getStatus() メソッドを呼び出して、初期のユーザー availability ステータスを SWF IM クライアントから受信することです。これは、次のように Web ページの updateStatus() 関数で行われます。
<script language="JavaScript">
...
function updateStatus()
{
if (swfReady)
{
var currentStatus = getSWF("IntrovertIMApp").getStatus();
document.forms["imForm"].status.value = currentStatus;
}
}
...
</script>
このコードでは、swfReady 変数の値が確認されます。この変数により、SWF ファイルのメソッドが ExternalInterface クラスに登録されたことが SWF ファイルからブラウザに通知されたかどうかが追跡されます。SWF ファイルで通信の受信準備ができている場合、その次の行 (var currentStatus = ...) では実際に IMManager クラスの getStatus() メソッドが呼び出されます。コードのこの行では、次の 3 つのことが行われます。
getSWF() JavaScript 関数が呼び出され、SWF ファイルを表す JavaScript オブジェクトへの参照が返されます。getSWF() に渡されたパラメータによって、HTML ページ内に複数の SWF ファイルが存在する場合にどのブラウザオブジェクトが返されるかが決まります。このパラメータに渡される値は、object タグの id 属性、および SWF ファイルの埋め込みに使用される embed タグの name 属性と一致している必要があります。getStatus() メソッドが呼び出されます。この場合、関数名 "getStatus" が使用されるのは、ExternalInterface.addCallback() を使用して ActionScript 関数がこの名前で登録されるからです。getStatus() ActionScript メソッドでは値が返され、その値が currentStatus 変数に割り当てられて、それがさらに status テキストフィールドのコンテンツ (value プロパティ) として割り当てられます。sendMessage() JavaScript 関数は、ActionScript 関数へのパラメータの受け渡しを示しています (sendMessage() は、ユーザーが HTML ページの [送信] ボタンを押したときに呼び出される関数です)。
<script language="JavaScript">
...
function sendMessage(message)
{
if (swfReady)
{
...
getSWF("IntrovertIMApp").newMessage(message);
}
}
...
</script>
newMessage() ActionScript メソッドにはパラメータが 1 つ必要なため、JavaScript コード内の newMessage() メソッドの呼び出しで JavaScript message 変数をパラメータとして使用することで、この変数が ActionScript に渡されます。
ブラウザがコンテンツにアクセスする方法はさまざまであるため、この例の getSWF() JavaScript 関数に示すように、必ず JavaScript を使用してユーザーが実行しているブラウザを検出すること、およびウィンドウまたはドキュメントオブジェクトを使用して、ブラウザ固有のシンタックスに従ってムービーにアクセスすることが重要です。
<script language="JavaScript">
...
function getSWF(movieName)
{
if (navigator.appName.indexOf("Microsoft") != -1)
{
return window[movieName];
}
else
{
return document[movieName];
}
}
...
</script>
スクリプトによってユーザーのブラウザタイプが検出されない場合、HTML コンテナの SWF ファイルを再生したときに予期しない動作が発生することがあります。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート
現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000345.html