事件機(jī)制的工作流程
關(guān)于事件流
目標(biāo)對象:派發(fā)事件的對象
當(dāng)事件發(fā)生后生成一個(gè)攜帶數(shù)據(jù)的對象,然后檢查目標(biāo)對象是否存在顯示層中,并遍歷從根容器一直到目標(biāo)對象所在位置的所有對象,以樹形勢表示。自動(dòng)檢測所經(jīng)過的節(jié)點(diǎn)是否注冊了監(jiān)聽器。
事件流暗運(yùn)行流程分為3步:
- 捕獲階段:捕獲事件 capturing,從根節(jié)點(diǎn)開始順序而下,檢測每個(gè)節(jié)點(diǎn)是否注冊了監(jiān)聽器。同時(shí),Flex 將事件對象的currentTarget 值改為當(dāng)前正在檢測的對象。如果注冊了監(jiān)聽器,則調(diào)用監(jiān)聽函數(shù)。
- 目標(biāo)階段:檢測目標(biāo)的監(jiān)聽器 targeting:觸發(fā)在目標(biāo)對象本身注冊的監(jiān)聽程序
- 冒泡階段:事件冒泡 bubbling:從目標(biāo)節(jié)點(diǎn)到根節(jié)點(diǎn),檢測每個(gè)節(jié)點(diǎn)是否注冊了監(jiān)聽器,如果有,則調(diào)用監(jiān)聽函數(shù)。
每個(gè)事件對象都有以下屬性:
target:事件的派發(fā)者
currentTarget:當(dāng)前正在檢測的的對象,幫助跟蹤事件傳播的過程。
默認(rèn)情況下,捕獲功能處于關(guān)閉狀態(tài),一般沒有必要進(jìn)行捕獲跟蹤。
事件只在bubbles 屬性為true
時(shí)才進(jìn)行冒泡,可以冒泡的事件包括:change、click、doubleClick、keyDown、keyUp、mouseDown、
mouseUp。并且不能在一個(gè)監(jiān)聽器中同時(shí)打開捕獲和冒泡功能,要做到這一點(diǎn),只能注冊兩個(gè)監(jiān)聽器,分別實(shí)現(xiàn)。
現(xiàn)在來看一個(gè)例子:
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
- <mx:Style source="style.css" />
-
- <mx:Script>
- <![CDATA[
- import flash.events.MouseEvent;
-
- internal function initApp():void{
- canvas_1.addEventListener(MouseEvent.CLICK,pressBtn,true);
- canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);
- btn_1.addEventListener(MouseEvent.CLICK,pressBtn);
- btn_2.addEventListener(MouseEvent.CLICK,pressBtn);
- }
- internal function output(msg:String):void{
- debug_txt.text += msg+"\n";
- }
- internal function pressBtn(evt:MouseEvent):void{
- output("是否冒泡--"+evt.bubbles);
- output("目標(biāo)對象-- "+evt.target+" -- "+evt.eventPhase);
- output("遍歷對象-- "+evt.currentTarget);
- output("------------");
- }
- ]]>
- </mx:Script>
- <mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="445" height="216">
- <mx:Text x="13" y="10" text="Canvas_1"/>
- <mx:Canvas id="canvas_2" styleName="box" x="10" y="102" width="173" height="90">
- <mx:Text x="10" y="10" text="Canvas_2"/>
- <mx:Button id = "btn_2" x="10" y="38" label="Button_2"/>
- </mx:Canvas>
- <mx:Button id="btn_1" x="16" y="38" label="Button_1"/>
- </mx:Canvas>
- <mx:TextArea id="debug_txt" styleName="textBox" x="37" y="304" height="198" width="445"/>
-
- </mx:Application>
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
<mx:Style source="style.css" />
<mx:Script>
<![CDATA[
import flash.events.MouseEvent;
internal function initApp():void{
canvas_1.addEventListener(MouseEvent.CLICK,pressBtn,true);
canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);
btn_1.addEventListener(MouseEvent.CLICK,pressBtn);
btn_2.addEventListener(MouseEvent.CLICK,pressBtn);
}
internal function output(msg:String):void{
debug_txt.text += msg+"\n";
}
internal function pressBtn(evt:MouseEvent):void{
output("是否冒泡--"+evt.bubbles);
output("目標(biāo)對象-- "+evt.target+" -- "+evt.eventPhase);
output("遍歷對象-- "+evt.currentTarget);
output("------------");
}
]]>
</mx:Script>
<mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="445" height="216">
<mx:Text x="13" y="10" text="Canvas_1"/>
<mx:Canvas id="canvas_2" styleName="box" x="10" y="102" width="173" height="90">
<mx:Text x="10" y="10" text="Canvas_2"/>
<mx:Button id = "btn_2" x="10" y="38" label="Button_2"/>
</mx:Canvas>
<mx:Button id="btn_1" x="16" y="38" label="Button_1"/>
</mx:Canvas>
<mx:TextArea id="debug_txt" styleName="textBox" x="37" y="304" height="198" width="445"/>
</mx:Application>
在監(jiān)聽函數(shù) pressBtn 中的屬性說明:
- target:派發(fā)事件的目標(biāo)對象
- currentTarget:事件流當(dāng)前正經(jīng)過的目標(biāo)對象
- bubbles:是否打開了冒泡功能
- eventPhase:事件流當(dāng)前的階段,1:捕獲,2:目標(biāo),3:冒泡
addEventListener(
type:String, 事件的類型
listener:Function, 監(jiān)聽函數(shù)
useCapture:Boolean = false, 是否打開捕獲功能
priority:int = 0, 監(jiān)聽器優(yōu)先級(jí)別
useWeakReference:Boolean = false 是否使用弱引用
)
如果useCapture 為true,打開了捕獲功能,則該組件的冒泡階段被取消。
只有可視化的對象有3個(gè)階段,而像XML等非可視化對象只有目標(biāo)階段。
8.2.2 事件對象
EventDispatcher 是派發(fā)事件的武器,經(jīng)它派發(fā)的事件對象必須是Event類型或者Event的子類。
Event對象中包含目標(biāo)對象存放的數(shù)據(jù),這些數(shù)據(jù)都成為Event的屬性,以供偵聽器使用:
Event的屬性:
- bubbles:只讀,布爾,事件是否開啟冒泡功能
- cancelable:只讀,布爾,處理事件的默認(rèn)行為是否可以停止。主要針對一些系統(tǒng)事件,如果值為true,則Event的preventDefault方法可以使用,否則不可用。
- currentTarget:只讀,對象,當(dāng)前正在調(diào)用監(jiān)聽器的對象
- eventPhase:只讀,整數(shù),返回事件流正經(jīng)歷的階段。1:捕獲,2:目標(biāo),3:冒泡
- target:只讀,派發(fā)事件的目標(biāo)對象
- type:只讀,字符,事件類型。比如鼠標(biāo)點(diǎn)擊事件的類型:click,并被定義為常量:MouseEvent.CLICK
構(gòu)造函數(shù):
Event(
type:String, 事件類型
bubbles:Boolean = false, 是否冒泡
cancelable:Boolean = false 是否可以停止
)
Event 的方法:
- isDefaultPrevented:判斷preventDefault 是否已經(jīng)被調(diào)用
- preventDefault:停止事件的默認(rèn)行為。針對一些系統(tǒng)事件,cancelable為true時(shí)才可用。
- stopImmediatePropagation:停止當(dāng)前的事件流傳播,包括當(dāng)前正在處理的對象
- stopPropagation:停止當(dāng)前的事件流傳播,但不會(huì)停止當(dāng)前正在處理的對象
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
- <mx:Style source="style.css" />
-
- <mx:Script>
- <![CDATA[
- import flash.events.MouseEvent;
-
- internal function initApp():void{
- canvas_1.addEventListener(MouseEvent.CLICK,CanvasHandler);
- canvas_2.addEventListener(MouseEvent.CLICK,CanvasHandler);
- canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);
- btn_1.addEventListener(MouseEvent.CLICK,pressBtn);
- }
- internal function output(msg:String):void{
- debug_txt.text += msg+"\n";
- }
-
- internal function pressBtn(evt:MouseEvent):void{
-
- output("是否冒泡--"+evt.bubbles);
- output("目標(biāo)對象-- "+evt.target+" -- "+evt.eventPhase);
- output("遍歷對象-- "+evt.currentTarget);
- output("------------");
- }
- internal function CanvasHandler(evt:MouseEvent):void{
-
- output("目標(biāo)對象-- "+evt.currentTarget+" -- "+evt.eventPhase);
- //停止事件流的傳播
- evt.stopImmediatePropagation();
- //evt.stopPropagation();
- }
- ]]>
- </mx:Script>
- <mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="425" height="160">
- <mx:Text x="13" y="10" text="Canvas_1"/>
- <mx:Canvas id="canvas_2" styleName="box" x="10" y="52" width="173" height="90">
- <mx:Text x="10" y="10" text="Canvas_2"/>
- <mx:Button id = "btn_1" x="10" y="38" label="Button_1"/>
- </mx:Canvas>
- </mx:Canvas>
- <mx:TextArea id="debug_txt" styleName="textBox" x="37" y="245" height="198" width="425"/>
-
- </mx:Application>
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
<mx:Style source="style.css" />
<mx:Script>
<![CDATA[
import flash.events.MouseEvent;
internal function initApp():void{
canvas_1.addEventListener(MouseEvent.CLICK,CanvasHandler);
canvas_2.addEventListener(MouseEvent.CLICK,CanvasHandler);
canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);
btn_1.addEventListener(MouseEvent.CLICK,pressBtn);
}
internal function output(msg:String):void{
debug_txt.text += msg+"\n";
}
internal function pressBtn(evt:MouseEvent):void{
output("是否冒泡--"+evt.bubbles);
output("目標(biāo)對象-- "+evt.target+" -- "+evt.eventPhase);
output("遍歷對象-- "+evt.currentTarget);
output("------------");
}
internal function CanvasHandler(evt:MouseEvent):void{
output("目標(biāo)對象-- "+evt.currentTarget+" -- "+evt.eventPhase);
//停止事件流的傳播
evt.stopImmediatePropagation();
//evt.stopPropagation();
}
]]>
</mx:Script>
<mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="425" height="160">
<mx:Text x="13" y="10" text="Canvas_1"/>
<mx:Canvas id="canvas_2" styleName="box" x="10" y="52" width="173" height="90">
<mx:Text x="10" y="10" text="Canvas_2"/>
<mx:Button id = "btn_1" x="10" y="38" label="Button_1"/>
</mx:Canvas>
</mx:Canvas>
<mx:TextArea id="debug_txt" styleName="textBox" x="37" y="245" height="198" width="425"/>
</mx:Application>
8.2.3 偵聽和響應(yīng)事件--一個(gè)偵聽鍵盤事件的例子
要偵聽一個(gè)事件,首先要?jiǎng)?chuàng)建一個(gè)函數(shù)來作為事件處理器,然后將這個(gè)函數(shù)注冊給相應(yīng)的時(shí)間類型。
this.addEventListener(KeyboardEvent.KEY_DOWN,keyHandler);
注冊鍵盤按下事件,交給keyHandler處理,也可以在Application標(biāo)簽添加事件:
keyDown="keyHandler(event)" 這種情況無法移除事件。
注冊了事件監(jiān)聽器,使用完畢后,必須使用removeEcentListener 方法刪除監(jiān)聽函數(shù):
removeEcentListener(
type:String, 事件類型
listener:Function, 監(jiān)聽函數(shù)
useCapture:Boolean = false 是否開啟捕獲功能,如果注冊時(shí)打開,移除也要打開。
)
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
- creationComplete="initApp()">
- <mx:Style source="style.css" />
- <mx:Script>
- <![CDATA[
- import flash.events.KeyboardEvent;
-
- internal function initApp():void{
- this.addEventListener(KeyboardEvent.KEY_DOWN,keyHandler);
- }
-
- private function keyHandler(e:KeyboardEvent):void{
-
- var str:String = "你按下的是: "+e.keyCode;
- debug_txt.text += str +"\n";
- }
- ]]>
- </mx:Script>
- <mx:TextArea id="debug_txt" styleName="textBox" x="25" y="78" height="198" width="212" editable="false"/>
- <mx:Text x="25" y="50" text="按鍵盤上的任意鍵"/>
- </mx:Application>