Flex 事件機制



1 關於事件流

目標對象:派發事件的對象
當事件發生後生成一個攜帶數據的對象,然後檢查目標對象是否存在顯示層中,並遍歷從根容器一直到目標對象所在位置的所有對象,以樹形勢表示。自動檢測所經過的節點是否註冊了監聽器。

事件流暗運行流程分爲3步:
  • 捕獲階段:捕獲事件 capturing,從根節點開始順序而下,檢測每個節點是否註冊了監聽器。同時,Flex 將事件對象的currentTarget 值改爲當前正在檢測的對象。如果註冊了監聽器,則調用監聽函數。
  • 目標階段:檢測目標的監聽器 targeting:觸發在目標對象本身註冊的監聽程序
  • 冒泡階段:事件冒泡 bubbling:從目標節點到根節點,檢測每個節點是否註冊了監聽器,如果有,則調用監聽函數。

每個事件對象都有以下屬性:
target:事件的派發者
currentTarget:當前正在檢測的的對象,幫助跟蹤事件傳播的過程。

默認情況下,捕獲功能處於關閉狀態,一般沒有必要進行捕獲跟蹤。
事件只在bubbles 屬性爲true 時才進行冒泡,可以冒泡的事件包括:change、click、doubleClick、keyDown、keyUp、mouseDown、 mouseUp。並且不能在一個監聽器中同時打開捕獲和冒泡功能,要做到這一點,只能註冊兩個監聽器,分別實現。

現在來看一個例子:
Xml代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">      
  3.     <mx:Style source="style.css" />  
  4.       
  5.     <mx:Script>  
  6.         <![CDATA[  
  7.             import flash.events.MouseEvent;  
  8.              
  9.             internal function initApp():void{  
  10.                 canvas_1.addEventListener(MouseEvent.CLICK,pressBtn,true);  
  11.                 canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);  
  12.                 btn_1.addEventListener(MouseEvent.CLICK,pressBtn);  
  13.                 btn_2.addEventListener(MouseEvent.CLICK,pressBtn);  
  14.             }  
  15.             internal function output(msg:String):void{  
  16.                 debug_txt.text += msg+"/n";  
  17.             }             
  18.             internal function pressBtn(evt:MouseEvent):void{  
  19.                 output("是否冒泡--"+evt.bubbles);  
  20.                 output("目標對象-- "+evt.target+" -- "+evt.eventPhase);  
  21.                 output("遍歷對象-- "+evt.currentTarget);  
  22.                 output("------------");  
  23.             }  
  24.         ]]>  
  25.     </mx:Script>  
  26.     <mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="445" height="216">  
  27.         <mx:Text x="13" y="10" text="Canvas_1"/>  
  28.         <mx:Canvas id="canvas_2" styleName="box" x="10" y="102" width="173" height="90">  
  29.             <mx:Text x="10" y="10" text="Canvas_2"/>  
  30.             <mx:Button id = "btn_2" x="10" y="38" label="Button_2"/>              
  31.         </mx:Canvas>  
  32.         <mx:Button id="btn_1" x="16" y="38" label="Button_1"/>  
  33.     </mx:Canvas>  
  34.     <mx:TextArea id="debug_txt" styleName="textBox" x="37" y="304" height="198" width="445"/>  
  35.       
  36. </mx:Application>  
  在監聽函數 pressBtn 中的屬性說明:
  • target:派發事件的目標對象
  • currentTarget:事件流當前正經過的目標對象
  • bubbles:是否打開了冒泡功能
  • eventPhase:事件流當前的階段,1:捕獲,2:目標,3:冒泡


addEventListener(
  type:String,    事件的類型
  listener:Function,    監聽函數
  useCapture:Boolean = false,    是否打開捕獲功能
  priority:int = 0,    監聽器優先級別
  useWeakReference:Boolean = false    是否使用弱引用
)

如果useCapture 爲true,打開了捕獲功能,則該組件的冒泡階段被取消。
只有可視化的對象有3個階段,而像XML等非可視化對象只有目標階段。

 

 

2 事件對象

EventDispatcher 是派發事件的武器,經它派發的事件對象必須是Event類型或者Event的子類。
Event對象中包含目標對象存放的數據,這些數據都成爲Event的屬性,以供偵聽器使用:
Event的屬性:
  • bubbles:只讀,布爾,事件是否開啓冒泡功能
  • cancelable:只讀,布爾,處理事件的默認行爲是否可以停止。主要針對一些系統事件,如果值爲true,則Event的preventDefault方法可以使用,否則不可用。
  • currentTarget:只讀,對象,當前正在調用監聽器的對象
  • eventPhase:只讀,整數,返回事件流正經歷的階段。1:捕獲,2:目標,3:冒泡
  • target:只讀,派發事件的目標對象
  • type:只讀,字符,事件類型。比如鼠標點擊事件的類型:click,並被定義爲常量:MouseEvent.CLICK

構造函數:
Event(
  type:String,    事件類型
  bubbles:Boolean = false,   是否冒泡
  cancelable:Boolean = false  是否可以停止
)

Event 的方法:
  • isDefaultPrevented:判斷preventDefault 是否已經被調用
  • preventDefault:停止事件的默認行爲。針對一些系統事件,cancelable爲true時纔可用。
  • stopImmediatePropagation:停止當前的事件流傳播,包括當前正在處理的對象
  • stopPropagation:停止當前的事件流傳播,但不會停止當前正在處理的對象

 

Xml代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">      
  3.     <mx:Style source="style.css" />  
  4.       
  5.     <mx:Script>  
  6.         <![CDATA[  
  7.             import flash.events.MouseEvent;  
  8.              
  9.             internal function initApp():void{  
  10.                 canvas_1.addEventListener(MouseEvent.CLICK,CanvasHandler);  
  11.                 canvas_2.addEventListener(MouseEvent.CLICK,CanvasHandler);  
  12.                 canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);  
  13.                 btn_1.addEventListener(MouseEvent.CLICK,pressBtn);  
  14.             }  
  15.             internal function output(msg:String):void{  
  16.                 debug_txt.text += msg+"/n";  
  17.             }  
  18.              
  19.             internal function pressBtn(evt:MouseEvent):void{  
  20.  
  21.                 output("是否冒泡--"+evt.bubbles);  
  22.                 output("目標對象-- "+evt.target+" -- "+evt.eventPhase);  
  23.                 output("遍歷對象-- "+evt.currentTarget);  
  24.                 output("------------");         
  25.             }  
  26.             internal function CanvasHandler(evt:MouseEvent):void{  
  27.                  
  28.                 output("目標對象-- "+evt.currentTarget+" -- "+evt.eventPhase);  
  29.                 //停止事件流的傳播  
  30.                 evt.stopImmediatePropagation();  
  31.                 //evt.stopPropagation();  
  32.             }  
  33.         ]]>  
  34.     </mx:Script>  
  35.     <mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="425" height="160">  
  36.         <mx:Text x="13" y="10" text="Canvas_1"/>  
  37.         <mx:Canvas id="canvas_2" styleName="box" x="10" y="52" width="173" height="90">  
  38.             <mx:Text x="10" y="10" text="Canvas_2"/>  
  39.             <mx:Button id = "btn_1" x="10" y="38" label="Button_1"/>              
  40.         </mx:Canvas>  
  41.     </mx:Canvas>  
  42.     <mx:TextArea id="debug_txt" styleName="textBox" x="37" y="245" height="198" width="425"/>  
  43.       
  44. </mx:Application>  

 

8.2.3 偵聽和響應事件--一個偵聽鍵盤事件的例子

要偵聽一個事件,首先要創建一個函數來作爲事件處理器,然後將這個函數註冊給相應的時間類型。
this.addEventListener(KeyboardEvent.KEY_DOWN,keyHandler);
註冊鍵盤按下事件,交給keyHandler處理,也可以在Application標籤添加事件:
keyDown="keyHandler(event)"  這種情況無法移除事件。

註冊了事件監聽器,使用完畢後,必須使用removeEcentListener 方法刪除監聽函數:
removeEcentListener(
  type:String,   事件類型
  listener:Function,   監聽函數
  useCapture:Boolean = false    是否開啓捕獲功能,如果註冊時打開,移除也要打開。
)

Xml代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"  
  3.      creationComplete="initApp()">  
  4.     <mx:Style source="style.css" />      
  5.     <mx:Script>  
  6.         <![CDATA[  
  7.             import flash.events.KeyboardEvent;  
  8.  
  9.             internal function initApp():void{  
  10.                 this.addEventListener(KeyboardEvent.KEY_DOWN,keyHandler);  
  11.             }  
  12.  
  13.             private function keyHandler(e:KeyboardEvent):void{  
  14.  
  15.                 var str:String = "你按下的是: "+e.keyCode;                 
  16.                 debug_txt.text += str +"/n";  
  17.             }  
  18.         ]]>  
  19.     </mx:Script>      
  20.     <mx:TextArea id="debug_txt" styleName="textBox" x="25" y="78" height="198" width="212" editable="false"/>  
  21.     <mx:Text x="25" y="50" text="按鍵盤上的任意鍵"/>  
  22. </mx:Application>  
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章