AIR における HTML 関連イベントの処理

Adobe AIR 1.0 およびそれ以降

イベント処理システムは、ユーザー入力やシステムイベントにプログラムが応答するための便利な仕組みです。Adobe® AIR® のイベントモデルは、便利なだけでなく、標準に準拠しています。業界標準のイベント処理アーキテクチャであるドキュメントオブジェクトモデル(DOM)Level 3 Events 仕様に基づいたイベントモデルにより、強力で直感的に使用できるイベント処理ツールが提供されます。

HTMLLoader イベント

HTMLLoader オブジェクトは、次の Adobe® ActionScript®3.0 イベントを送出します。

イベント

説明

htmlDOMInitialize

HTML ドキュメントが作成されたとき(ただし、スクリプトが解析される前、または DOM ノードがページに追加される前)に送出されます。

complete

読み込み操作に対する応答として HTML DOM が作成されたとき(HTML ページの onload イベントの直後)に送出されます。

htmlBoundsChanged

contentWidth および contentHeight プロパティの一方または両方が変更されたときに送出されます。

locationChange

HTMLLoader の location プロパティが変更されたときに送出されます。

locationChanging

ユーザーによるナビゲーション、JavaScript の呼び出しまたはリダイレクトにより、HTMLLoader の location が変更される前に送出されます。 locationChanging イベントは、 load() loadString() reload() historyGo() historyForward() または historyBack() メソッドの呼び出し時には送出されません。

送出されたイベントオブジェクトの preventDefault() メソッドを呼び出すと、ナビゲーションがキャンセルされます。

システムブラウザーでリンクが開いている場合、HTMLLoader は location を変更しないので、locationChanging イベントは送出されません。

scroll

HTML エンジンがスクロール位置を変更するたびに送出されます。scroll イベントは、ページ内のアンカーリンク( # リンク)への移動、または window.scrollTo() メソッドの呼び出しによって発生します。テキスト入力欄またはテキスト領域にテキストを入力した場合にも、scroll イベントが発生する可能性があります。

uncaughtScriptException

HTMLLoader で JavaScript 例外が発生し、その例外が JavaScript コードでキャッチされない場合に送出されます。

AIR クラスのイベント処理と HTML DOM の他のイベント処理との相違

HTML DOM では、イベントを処理する方法がいくつかあります。

  • on イベントハンドラーを HTML エレメントの開始タグで定義します。例を次に示します。

    <div id="myDiv" onclick="myHandler()">
  • コールバック関数プロパティ。例を次に示します。

    document.getElementById("myDiv").onclick 
  • addEventListener() メソッドを使用して登録するイベントリスナー。例を次に示します。

    document.getElementById("myDiv").addEventLister("click", clickHandler)

ただし、ランタイムオブジェクトは DOM では使用されないので、イベントリスナーを追加するには、AIR オブジェクトの addEventListener() メソッドを呼び出すことが唯一の方法です。

JavaScript の場合と同様に、AIR オブジェクトから送出されるイベントは、デフォルト動作と関連付けることができます( デフォルト動作 とは、ある種のイベントに対する通常の結果として AIR で実行されるアクションのことです)。

ランタイムオブジェクトが送出するイベントオブジェクトは、Event クラスまたはそのサブクラスのインスタンスです。イベントオブジェクトには、特定のイベントに関する情報が格納されているのに加え、イベントオブジェクトを操作する際に役立つメソッドが備わっています。例えば AIR は、ファイルの非同期読み取り中に I/O エラーイベントを検出すると、イベントオブジェクト(IOErrorEvent クラスのインスタンス)を作成し、その特定の I/O エラーイベントを表します。

イベントハンドラーコードを作成する場合、そのコードは次のような同じ基本構造に基づいています。

function eventResponse(eventObject) 
{ 
    // Actions performed in response to the event go here. 
} 
 
eventTarget.addEventListener(EventType.EVENT_NAME, eventResponse);

このコードは 2 つのことを行います。まず、ハンドラー関数を定義します。これにより、イベントに対する応答として実行されるアクションを指定します。次に、ソースオブジェクトの addEventListener() メソッドを呼び出します。これは実際には、指定したイベントに対して関数を登録し、イベントが発生したときにハンドラーアクションが実行されるようにするための処理です。イベントが実際に発生すると、イベントターゲットは、イベントリスナーに登録されているすべての関数とメソッドのリストを確認します。次にイベントターゲットは、リストの関数とメソッドを順に呼び出し、イベントオブジェクトをパラメーターとして渡します。

デフォルト動作

イベントに応答するコードは、通常は開発者が記述します。しかし、イベントに対して何らかの決まった動作が非常によく行われる場合については、一般的な処理が AIR によって自動的に実行されるようになっています(開発者が特にこの動作をキャンセルするためのコードを記述した場合を除く)。AIR によって自動的に実行されるそうした動作を、デフォルト動作と呼びます。

例えば、ユーザーがアプリケーションのウィンドウにある閉じるボックスをクリックする場合には、ウィンドウが閉じることが期待されているため、この動作は AIR にビルトインされています。このデフォルト動作が不要な場合は、イベント処理システムを使用することでキャンセルできます。ユーザーがウィンドウの閉じるボックスをクリックすると、そのウィンドウを表す NativeWindow オブジェクトが closing イベントを送出します。ランタイムがウィンドウを閉じないようにするには、送出したイベントオブジェクトの preventDefault() メソッドを呼び出す必要があります。

デフォルト動作の中には、キャンセルできないものもあります。例えばこのランタイムは、FileStream オブジェクトがデータをファイルに書き込む際に、OutputProgressEvent オブジェクトを生成します。この場合、ファイルの内容が新しいデータで更新されることがデフォルト動作となります。このデフォルト動作はキャンセルできません。

多くの種類のイベントオブジェクトには、デフォルト動作が関連付けられていません。例えば Sound オブジェクトは、ID3 情報を提供するために十分なデータが MP3 ファイルから読み取られると、 id3 イベントを送出しますが、デフォルト動作は関連付けられていません。API ドキュメントの Event クラスとそのサブクラスに関する項目には、各種イベントの一覧と、関連付けられたデフォルト動作がある場合はその内容、およびデフォルト動作をキャンセルできるかどうかが説明されています。

注意: デフォルト動作は、ランタイムによって直接送出されるイベントオブジェクトにのみ関連付けられており、JavaScript で作成したプログラムによって送出されるイベントオブジェクトに関連付けられたデフォルト動作は存在しません。例えば、EventDispatcher クラスのメソッドを使用してイベントオブジェクトを送出できますが、イベントを送出してもデフォルト動作はトリガーされません。

イベントフロー

AIR で実行される SWF ファイルコンテンツは、ビジュアルコンテンツの表示に ActionScript 3.0 表示リストアーキテクチャを使用します。ActionScript 3.0 表示リストは、コンテンツの親子関係を設定すると共に、親と子の表示オブジェクトの間で伝達される、SWF ファイルコンテンツのイベント(例えばマウスクリックイベント)の親子関係を設定します。HTML DOM には、DOM エレメント間でのみやり取りされる、専用の独立したイベントフローがあります。AIR 向けに HTML ベースのアプリケーションを作成する場合、開発者は ActionScript 3.0 表示リストではなく HTML DOM を主に使用するので、AIR リファレンスドキュメントに記載されているイベントフェーズに関する情報は、通常は無視してかまいません。

Adobe AIR イベントオブジェクト

イベント処理システムにおいて、イベントオブジェクトには主として 2 つの用途があります。1 つは、個々のイベントに関する情報を各種プロパティに格納して、具体的なイベントを表現することです。もう 1 つは、各種メソッドを使用してイベントオブジェクトを操作し、イベント処理システムの動作を変化させることです。

AIR API では、各 AIR API クラスから送出されるすべてのイベントオブジェクトの基本クラスとなる Event クラスが定義されています。Event クラスは、すべてのイベントオブジェクトに共通する基本的なプロパティとメソッドを備えています。

Event オブジェクトを使用する場合は、最初に Event クラスのプロパティとメソッド、および Event クラスのサブクラスの機能について理解することが重要です。

Event クラスのプロパティについて

Event クラスでは、イベントに関する重要な情報を提供する、いくつかの読み取り専用プロパティおよび定数が定義されています。特に重要なものを次に示します。

  • Event.type は、イベントオブジェクトが表すイベントのタイプを示します。

  • Event.cancelable は、そのイベントに関連付けられているデフォルト動作(存在する場合)がキャンセル可能かどうかを報告するブール値です。

  • イベントフロー情報はその他のプロパティに格納され、AIR で実行される SWF コンテンツで ActionScript 3.0 を使用している場合にのみ使用されます。

イベントオブジェクトのタイプ

すべてのイベントオブジェクトには、それぞれイベントタイプが設定されます。イベントタイプはストリング値として Event.type プロパティに格納されます。イベントオブジェクトのタイプを知ることができると、コードを作成する際に、タイプに応じてオブジェクトの処理方法を区別できて便利です。例えば次のコードでは、 myFileStream によって送出される complete イベントに応答する fileReadHandler() リスナー関数を登録します。

myFileStream.addEventListener(Event.COMPLETE, fileReadHandler);

AIR の Event クラスでは、ランタイムオブジェクトによって送出されるイベントのタイプを表す COMPLETE CLOSING および ID3 などの多数のクラス定数が定義されています。これらの定数については、『 HTML 開発者用 Adobe AIR API リファレンスガイド 』の Event クラスのページで説明されています。

イベント定数を使用すると、特定のイベントタイプを簡単に参照できます。ストリング値の代わりに定数を使用することで、入力ミスをよりすばやく見つけることができます。コード内の定数名にスペルミスがある場合、JavaScript パーサによってその誤りが検出されます。定数名ではなく、イベントストリングにスペルミスがあると、イベントハンドラーは、決して送出されることのないタイプのイベントについて登録されることになります。そのため、イベントリスナーを追加する場合は、次のコードを使用することをお勧めします。

myFileStream.addEventListener(Event.COMPLETE, htmlRenderHandler);

次のコードはお勧めできません。

myFileStream.addEventListener("complete", htmlRenderHandler);

デフォルト動作に関する情報

コードで cancelable プロパティを調べることにより、特定のイベントオブジェクトに対するデフォルト動作をキャンセルできるかどうかを知ることができます。 cancelable プロパティの値は Boolean 型で、デフォルト動作がキャンセル可能かどうかを示します。デフォルト動作をキャンセルできるイベントは少数ですが、キャンセルできる場合は、関連付けられた動作を preventDefault() メソッドで無効化できます。詳しくは、 イベントのデフォルト動作のキャンセル を参照してください。

Event クラスのメソッドについて

Event クラスのメソッドは、次の 3 種類に大別されます。

  • ユーティリティメソッド:イベントオブジェクトのコピーを作成するか、またはストリングに変換します。

  • イベントフローメソッド:イベントフローからイベントオブジェクトを削除します(主としてランタイムの SWF コンテンツで ActionScript 3.0 を使用する場合に使用します。 イベントフロー を参照してください)。

  • デフォルト動作メソッド:デフォルト動作をキャンセルするか、またはキャンセル済みかどうかを確認します。

Event クラスのユーティリティメソッド

Event クラスには、2 種類のユーティリティメソッドがあります。 clone() メソッドは、イベントオブジェクトのコピーを作成します。 toString() メソッドは、イベントオブジェクトの各種プロパティとそれらの値を表すストリング表現を生成します。

イベントのデフォルト動作のキャンセル

デフォルト動作のキャンセルに関連するメソッドには、 preventDefault() メソッドと isDefaultPrevented() メソッドの 2 つがあります。 preventDefault() メソッドを呼び出すと、イベントに関連付けられたデフォルト動作をキャンセルできます。あるイベントオブジェクトについて preventDefault() が既に呼び出されているかどうかを確認するには、 isDefaultPrevented() メソッドを使用します。

preventDefault() メソッドは、イベントのデフォルト動作がキャンセル可能な場合にのみ機能します。あるイベントに対する動作がキャンセル可能かどうかを確認するには、API ドキュメントを参照するか、またはイベントオブジェクトの cancelable プロパティを調べます。

デフォルト動作をキャンセルしても、イベントフローによるイベントオブジェクト処理の進行には影響しません。イベントフローからイベントオブジェクトを削除するには、Event クラスのイベントフローメソッドを使用します。

Event クラスのサブクラス

多くのイベントは、Event クラスに定義されている共通のプロパティセットを使用すれば十分に表現できます。しかし、それ以外のイベントを表現するためには、Event クラスでは提供されていないプロパティが必要になります。そのようなイベントのために、AIR API には Event クラスのサブクラスがいくつか定義されています。

各サブクラスには、そのイベントのカテゴリに特有のプロパティおよびイベントタイプが追加されています。例えば、マウス入力に関連するイベントには、イベントが発生した時点でのマウスの位置を示すプロパティがあります。同様に、InvokeEvent クラスを使用すると、呼び出すファイルのファイルパスと、コマンドライン呼び出しでパラメーターとして渡される引数を格納するプロパティを追加できます。

多くの Event サブクラスでは、そのサブクラスに関連付けられているイベントタイプを表す追加の定数が定義されています。例えば、FileListEvent クラスでは、 directoryListing および selectMultiple イベントタイプを表す定数が定義されています。

JavaScript を使用したランタイムイベントの処理

ランタイムクラスでは、 addEventListener() メソッドを使用することで、イベントハンドラーを追加できます。あるイベントに対するハンドラー関数を追加するには、そのイベントを送出したオブジェクトの addEventListener() メソッドを呼び出し、イベントタイプと処理関数を指定します。例えば、ユーザーがウィンドウのタイトルバーにある閉じるボタンをクリックしたときに送出される closing イベントをリッスンするには、次のステートメントを使用します。

window.nativeWindow.addEventListener(air.NativeWindow.CLOSING, handleWindowClosing);

addEventListener() メソッドの type パラメーターはストリングですが、AIR API では、すべてのランタイムイベントタイプに対して定数が定義されています。これらの定数を使用すると、ストリング version を使用するよりも、type パラメーターに入力したスペルの誤りを発見しやすくなります。

イベントハンドラー関数の作成

次のコードでは、メインウィンドウの位置に関する情報を表示する簡単な HTML ファイルを作成します。ハンドラー関数は moveHandler() という名前で、メインウィンドウの move イベント(NativeWindowBoundsEvent クラスによって定義されています)をリッスンします。

<html> 
    <script src="AIRAliases.js" /> 
    <script> 
        function init() { 
            writeValues(); 
            window.nativeWindow.addEventListener(air.NativeWindowBoundsEvent.MOVE, 
                                                     moveHandler); 
        } 
        function writeValues() { 
            document.getElementById("xText").value = window.nativeWindow.x; 
            document.getElementById("yText").value = window.nativeWindow.y; 
        } 
        function moveHandler(event) { 
            air.trace(event.type); // move 
            writeValues(); 
        } 
    </script> 
    <body onload="init()" /> 
        <table> 
            <tr> 
                <td>Window X:</td> 
                <td><textarea id="xText"></textarea></td> 
            </tr> 
            <tr> 
                <td>Window Y:</td> 
                <td><textarea id="yText"></textarea></td> 
            </tr> 
        </table> 
    </body> 
</html>

ユーザーがウィンドウを移動すると、textarea エレメントにウィンドウの更新された X および Y 位置が表示されます。

イベントオブジェクトが引数として moveHandler() メソッドに渡されています。この event パラメーターにより、ハンドラー関数はイベントオブジェクトを確認できます。この例では、イベントオブジェクトの type プロパティを使用して、イベントが move イベントであることを報告しています。

注意: listener パラメーターを指定する際には、括弧を使用しないでください。例えば、次に示す addEventListener() メソッドの呼び出しでは、 moveHandler() 関数が括弧なしで指定されています。 addEventListener(Event.MOVE, moveHandler)

addEventListener() メソッドには、他にも 3 つのパラメーター( useCapture priority 、および useWeakReference )があります。詳しくは、『 HTML 開発者用 Adobe AIR API リファレンスガイド 』を参照してください。

イベントリスナーの削除

不要になったイベントリスナーを削除するには、 removeEventListener() メソッドを使用します。不要になったリスナーは削除することをお勧めします。必須パラメーターには eventName および listener があります。これらは、 addEventListener() メソッドの必須パラメーターと同じです。

移動する HTML ページでのイベントリスナーの削除

HTML コンテンツを移動する場合、または HTML コンテンツを格納しているウィンドウが閉じられたためにそのコンテンツが破棄される場合、読み込みを解除されたページ上のオブジェクトを参照するイベントリスナーは、自動的には削除されません。オブジェクトが既に読み込みを解除されたハンドラーにイベントを送出すると、「The application attempted to reference a JavaScript object in an HTML page that is no longer loaded.」というエラーメッセージが表示されます。

このエラーを回避するには、HTML ページが読み込みを解除される前に、ページ内の JavaScript イベントリスナーを削除します。(HTMLLoader オブジェクト内での)ページナビゲーションの場合には、イベントリスナーを window オブジェクトの unload イベントの処理中に削除します。

例えば、次の JavaScript コードでは、 uncaughtScriptException イベントをリッスンするイベントリスナーを削除します。

window.onunload = cleanup; 
window.htmlLoader.addEventListener('uncaughtScriptException', uncaughtScriptException); 
function cleanup() 
{ 
    window.htmlLoader.removeEventListener('uncaughtScriptException', 
                            uncaughtScriptExceptionHandler); 
}

HTML コンテンツを格納したウィンドウを閉じる際にエラーが発生しないようにするには、NativeWindow オブジェクト( window.nativeWindow )の closing イベントに対する応答として、cleanup 関数を呼び出します。例えば、次の JavaScript コードでは、 uncaughtScriptException イベントをリッスンするイベントリスナーを削除します。

window.nativeWindow.addEventListener(air.Event.CLOSING, cleanup); 
function cleanup() 
{ 
    window.htmlLoader.removeEventListener('uncaughtScriptException', 
                            uncaughtScriptExceptionHandler); 
}

また、イベントの処理が 1 回のみの場合、実行後すぐにイベントリスナーを削除することで、このエラーが発生しないようにできます。例えば、次の JavaScript コードでは、HTMLLoader クラスの createRootWindow() メソッドを呼び出し、 complete イベントのイベントリスナーを追加することで、html ウィンドウを作成します。 complete イベントハンドラーは、呼び出されると、 removeEventListener() 関数を使用して自身のイベントリスナーを削除します。

var html = runtime.flash.html.HTMLLoader.createRootWindow(true); 
html.addEventListener('complete', htmlCompleteListener); 
function htmlCompleteListener() 
{ 
    html.removeEventListener(complete, arguments.callee) 
    // handler code.. 
} 
html.load(new runtime.flash.net.URLRequest("second.html"));

また、不要なイベントリスナーを削除することで、システムのガベージコレクタは、これらのリスナーに関連付けられていたメモリを再生できます。

既存のイベントリスナーの確認

hasEventListener() メソッドを使用することで、あるオブジェクトに関してイベントリスナーが存在しているかどうかを確認することができます。

エラーイベントのリスナーを登録しない場合

例外(イベントではなく)は、ランタイムクラスでのエラー処理に関する主要なメカニズムです。しかし例外処理は、ファイルの読み込みなどの非同期操作に対しては機能しません。非同期操作の実行中にエラーが発生すると、ランタイムによりエラーイベントオブジェクトが送出されます。エラーイベントについてリスナーを作成しない場合は、AIR Debug Launcher により、エラーに関する情報を含むダイアログボックスが表示されます。

ほとんどのエラーイベントは ErrorEvent クラスに基づいていて、説明的なエラーメッセージを格納するために使用される text という名前のプロパティを備えています。例外は StatusEvent クラスで、 text プロパティの代わりに level プロパティを備えています。 level プロパティの値が error の場合、StatusEvent はエラーイベントと見なされます。

エラーイベントが発生しても、アプリケーションの実行は停止されません。エラーイベントは、AIR Debug Launcher のダイアログボックスとしてのみ表示されます。ランタイムで実行されているインストール済み AIR アプリケーションでは一切表示されません。