關於AS3的事件移除釋疑

as3.0中的事件Event(位於包flash.events內,繼承至Object,子類有…)

既然是釋疑,主要是在與同事聊天的過程中提及的幾個問題:

1、addEventListener重複監聽是否會被多次調用?

2、如何移除一個匿名函數的監聽?

3、target、currentTarget之間的區別

4、關於Event對象的其它需要注意的地方

/*****************************************

*  addEventListener重複監聽是否會被多次調用?

******************************************/

這裏重點在於“重複”兩個字,如果監聽一個對象,事件類型相同,監聽函數也是相同,則該監聽函數在事件被觸發時只被調用一次。如果監聽的事件類型不同或是監聽函數不同,則該監聽函數,在該事件類型被觸發時調用。

上面的寫法,onClickHandler函數在對象的CLICK事件被觸發時被調用一次。

使用removeEventListener則會移除該事件,CLICK事件被觸發時不再調用onClickHandler函數。

如果監聽函數爲匿名函數:

需要移除匿名函數時,一是可以使用變量保存該匿名函數的引用,二是可以在該匿名函數內使用arguments.callee獲取該匿名函數的引用,使用removeEventListener移除對指定事件類型的監聽。

使用閉包獲得的匿名函數,每次調用時獲得的匿名函數都不是同一個引用,所以對事件的監聽將會被多次調用。例如有一個函數爲:getClickFn()。

當多次使用該函數進行監聽時,將會被多次調用。

而addEventListener方法,屬於類EventDispatcher(flash.events,繼承至Object,實現IEventDispatcher),子類有(DisplayObject…)

該方法有5個參數。addEventListener(eventType, listenerFn, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false);

一般很少用到後面的參數,分別是:

useCapture –> 是否在捕獲階段監聽事件,默認在冒泡階段進行監聽

priority –> 默認爲0,也就是監聽事件時,回調監聽函數的“層次”順序,比如之後監聽的函數要在事件觸發時有攔截操作等(取消事件冒泡,阻止其後事件的觸發stopPropagation、stopImmediatePropagation)

useWeakReference –>  是否爲弱引用,強烈建議避免使用該參數,不易控制。

hasEventListener用來檢查對象是否爲特定的事件類型註冊了監聽器。

/*****************************************

* target、currentTarget的區別

******************************************/

這個是比較容易混淆,但也非常常見。一句話概括來講就是:

target -- 觸發事件的事件源,currentTarget -- 觸發事件的監聽對象。

/*****************************************

* 關於Event其它要注意的地方

******************************************/

首先要很清楚,一個事件它經歷了哪幾個階段:捕獲階段 –> 目標階段 –> 冒泡階段

然後就是stopPropagation、stopImmediatePropagation這兩個方法它們的區別,寫個例子就知道了<從方法的說明中就能知道大概意思,寫個Demo加深印象就可以了>

寫了一堆,最後還是寫一個demo,比較實際一點:

1: package  

       2: {

       3:     import flash.display.MovieClip;

       4:     import flash.display.Sprite;

       5:     import flash.events.MouseEvent;

       6:     import flash.filters.GlowFilter;

       7:     import flash.text.TextField;

       8:     import flash.text.TextFieldAutoSize;

       9:     import flash.text.TextFieldType;

      10:     import flash.text.TextFormat;

      11:     /**

      12:      * ...

      13:      * @author Meteoric

      14:      */

      15:     public class EventDemo extends Sprite

      16:     {

      17:         

      18:         public function EventDemo() 

      19:         {

      20:             initView();

      21:         }

      22:         

      23:         private var txt:TextField;

      24:         

      25:         private function getTextGlowFilter(colorVal:uint=0x000000, blur:Number=2):GlowFilter

      26:         {

      27:             var color:uint = colorVal;

      28:             var alpha:Number = 1;

      29:             var blurX:Number = blur;

      30:             var blurY:Number = blur;

      31:             var strength:Number = 255;

      32:             var quality:Number = 1;

      33:             

      34:             return new GlowFilter(color, alpha, blurX, blurY, strength, quality);

      35:         }

      36:         

      37:         private function initView():void

      38:         {

      39:             txt = new TextField();

      40:             txt.x = 200;

      41:             txt.y = 50;

      42:             txt.selectable = false;

      43:             txt.mouseEnabled = false;

      44:             txt.autoSize = TextFieldAutoSize.LEFT;

      45:             txt.width = 350;

      46:             //txt.height = 100;

      47:             txt.wordWrap = true;

      48:             txt.multiline = true;

      49:             txt.type = TextFieldType.INPUT;

      50:             txt.background = true;

      51:             txt.backgroundColor = 0x232323;

      52:             

      53:             var txtfor:TextFormat = new TextFormat();

      54:             txtfor.size = 15;

      55:             txtfor.font = "verdana";

      56:             txtfor.bold = true;

      57:             txtfor.color = 0xffffff;

      58:             

      59:             txt.defaultTextFormat = txtfor;

      60:             txt.filters = [getTextGlowFilter(0xffcc66)];

      61:             

      62:             addChild(txt);

      63:             

      64:             //監聽事件

      65:             var mc:MovieClip = new MovieClip();

      66:             

      67:             mc.graphics.clear();

      68:             mc.graphics.beginFill(0xcc0000, .7);

      69:             mc.graphics.drawCircle(100, 100, 50);

      70:             mc.graphics.endFill();

      71:             

      72:             addChild(mc);

      73:             

      74:             mc.buttonMode = true;

      75:             

      76:             

      77:             //重複的監聽只會被調用一次

      78:             mc.addEventListener(MouseEvent.CLICK, onClickHandler);

      79:             mc.addEventListener(MouseEvent.CLICK, onClickHandler);

      80:             mc.addEventListener(MouseEvent.CLICK, onClickHandler);

      81:             

      82:             //檢測是否綁定了指定的事件

      83:             setTxt('是否監聽了MouseEvent.CLICK事件:' + mc.hasEventListener(MouseEvent.CLICK));

      84:             

      85:             //移除指定的監聽事件

      86:             mc.removeEventListener(MouseEvent.CLICK, onClickHandler);

      87:             

      88:             //重複監聽的事件,移除一次後將不再被監聽

      89:             setTxt('是否監聽了MouseEvent.CLICK事件:' + mc.hasEventListener(MouseEvent.CLICK));

      90:             

      91:             //使用匿名函數進行事件的監聽

      92:             mc.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {

      93:                     var _mc:MovieClip = e.target as MovieClip;

      94:                     _mc.removeEventListener(MouseEvent.CLICK, arguments.callee);

      95:                     

      96:                     setTxt('~~haha~~我就是匿名函數【remove】');

      97:                 });

      98:                 

      99:             //下面使用getClickFn獲得的是兩個不同的匿名函數引用                

     100:             mc.addEventListener(MouseEvent.CLICK, getClickFn(100, function(fn:Function, evt:MouseEvent):void {

     101:                     

     102:                     var _mc:MovieClip = evt.target as MovieClip;

     103:                     

     104:                     _mc.removeEventListener(MouseEvent.CLICK, fn);

     105:                     

     106:                     setTxt("~~hehe~~另外一個匿名函數【remove】");

     107:                     

     108:                 }), false, 1);

     109:             

     110:             mc.addEventListener(MouseEvent.CLICK, getClickFn(50));

     111:         }

     112:         

     113:         private function onClickHandler(e:MouseEvent):void 

     114:         {

     115:             setTxt("----onClickHandler" + getNow());

     116:         }

     117:         

     118:         private function getClickFn(n:Number=0, fn:Function=null):Function

     119:         {

     120:             var num:Number = n;

     121:             

     122:             return function(evt:MouseEvent):void {                

     123:                 fn && fn(arguments.callee, evt);

     124:                 

     125:                 setTxt('當前num的值:' + (++num));

     126:             }

     127:         }

     128:         

     129:         private function getNow():String

     130:         {

     131:             var date:Date = new Date();

     132:             var year:Number = date.getFullYear();

     133:             var month:Number = date.getMonth() + 1;

     134:             var day:Number = date.getDay();

     135:             

     136:             var hours:Number = date.getHours();

     137:             var minutes:Number = date.getMinutes();

     138:             var seconds:Number = date.getSeconds();

     139:             

     140:             return [year, month, day].join("-") + " " + [hours, minutes, seconds].join(":");

     141:         }

     142:         

     143:         private function setTxt(str:String):void

     144:         {

     145:             txt.appendText(str + '\n');

     146:             

     147:             trace(str);

     148:         }

     149:         

     150:     }

     151:  

     152: }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章