關於AS3的事件移除釋疑


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

image

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

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

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

3、target、currentTarget之間的區別

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

 

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

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

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

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

image

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

image

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

 

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

image

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

 

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

image

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

image

 

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

image

該方法有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: }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM