Web システムのツボ

【AS3】 addEventListenerに引数を渡す

複数のオブジェクトにイベントを追加する場合、イベント発生時の処理で
どのオブジェクトか識別したい場合があります。

例えば、多数あるボタンにクリックイベントを纏めて登録する場合、

【一括でイベントを登録するサンプル
// ボタン格納配列
var btn_array:Array = new Array(btn1_mc, btn2_mc, btn3_mc, ...);

for(var i:int=0; i<btn_array.length; i++){
    // マウスイベント登録
    btn_array[i].addEventListener(MouseEvent.CLICK, onMouseClickHandler);
}

/**
 * マウスイベント
 */
function onMouseClickHandler(e:MouseEvent):void
{
    var btn_mc:MovieClip = MovieClip(e.target);
    // "btn_mc"って、btn_array配列のどのボタンが押された?
}

登録イベント発生時に、どのボタン押されたのか判別できません。
nameプロパティで出来なくはないですが、出来れば配列で回したいですよね。

この場合は、ムービークリップに対してイベントを張っているので、
予め識別できるidなどプロパティを追加しておけば楽に判別できます。

【ムービークリップに識別idを追加するサンプル
for(var i:int=0; i<btn_array.length; i++){
    // 識別id追加
    btn_array[i]._id = i;
    // マウスイベント登録
    btn_array[i].addEventListener(MouseEvent.CLICK, onMouseClickHandler);
}

/**
 * マウスイベント
 */
function onMouseClickHandler(e:MouseEvent):void
{
    // btn_array[e.target._id] が押されました!
}


というように、予め識別できるidなどを追加しておけば判別出来ます。

ただ、全てこのような形で出来るわけではなく、例えば画像読み込みに使用するloaderには、
プロパティを追加できません。

【プロパティを追加できないサンプル
// 画像ファイル名格納配列
var img_array:Array = new Array('img1.jpg', 'img2.jpg', 'img3.jpg', ...);

for(var i:int=0; i<img_array.length; i++){
    var myLoader:Loader = new Loader();
    myLoader._id = i;    // プロパティを追加できない、※エラー
    myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler );
    // 読み込み開始
    myLoader.load(new URLRequest(img_array[i]));
}

/**
 * 読み込み完了イベント
 */
function onCompleteHandler(e:Event):void
{
    // どの画像が読み込み完了した?
}


そこで、loaderなどのイベント発生時に引数を渡す方法をご紹介します。

そもそもaddEventListenerの構文は、addEventListener(イベント名、リスナー関数);
となっています。
一番簡単な方法は、このリスナー関数にループで使用しているカウンタ(i)を渡してあげれば
済む話なのですが、リスナー関数の引数はリファレンスにも書かれている通り、

この関数は、次の例のように、Event オブジェクトを唯一のパラメータとして受け取り、
何も返さないものである必要があります。
function(evt:Event):void
引用:ActionScript 3.0 コンポーネントリファレンスガイド
http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/flash/events/EventDispatcher.html

となっています。つまり、

/**
 * リスナー関数
 */
function(e:Event):void
{
    
}

という形でないといけないのです。これではループカウンタを渡すことが出来ません。
そこで、リスナー関数の構文を守り、かつループカウンタを渡す方法はこのようになります。

【AddEventListenerに引数を渡すサンプル
for(var i:int=0; i<img_array.length; i++){
    var myLoader:Loader = new Loader();
    myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler(i));
    
    // 読み込み開始
    myLoader.load(new URLRequest(img_array[i]));
}

/**
   * 読み込み完了イベント
   */
function onCompleteHandler(_num:int):Function
{
    // img_array[_num] 画像が読み込み完了しました!
    
    return function(e:Event):void;
}



パラメータを受け取る関数(onCompleteHandler)を間に挟み、且つ構文を守る為
Event型を唯一の引数とした戻り値なしの関数をリターンしてあげれば完了です。

(tsubasa)
 

Webシステムのツボとは

オープンソースの紹介や、プログラミング講座、フリーソフトのレビューなど、Webエンジニアが送る、つれづれ日記。
【隔週金曜日更新】

運営会社:株式会社ジーピーオンライン

RSSを購読する

Monthly Archive