Flash AS3 學習12 - 事件處理機制

先來看個例子:
地點:飯館類(extend Sprite or UIcomponent...,是個容器就行)
人物:客人類(extend EventDispatcher,會說話就行)、廚師類(extend Object,能

滿足客人需求就行)

一、四個步驟:註冊偵聽、分發事件、偵聽事件、移除偵聽。
(1)、註冊偵聽:客人進入飯館,使用addEventListener指定某廚師準備做菜。
(2)、分發事件:客人使用dispatchEvent對廚師進行喊話,表示我要喫什麼。喊話內

容被放在Event類或其子類裏,主要包括類型、目標和數據三部分。類型(Type)就是點

菜,而不是結賬,上酒水。目標(Target)用來記錄是哪桌的客人。數據(Data)用來保

存重要信息,如果是點菜,那記的就是菜名。
(3)、偵聽事件:根據註冊偵聽中的需求,廚師開始做菜。
(4)、移除偵聽:不移除的後果就是,以後在任意餐館裏喊話叫菜,所有註冊過偵聽的

餐館廚師都開始做菜。
一些細節:
(1)、爲了方便客人類在飯館類中使用MXML標籤註冊偵聽,常常在客人類中使用Event

標籤。比如[Event(name="onChange", type="components.MyEventTest")]
(2)、註冊偵聽時,可以使用弱引用,即更改addEventListener中的useWeakReference

屬性的默認值false爲true。這樣垃圾回收器會檢測弱引用偵聽並自動移除,極其不建

議這樣做,而是直接移除偵聽。
(3)、當客人類已經繼承了某類,無法再繼承EventDispatcher時,可以考慮實現

IEventDispatcher接口。額外地,需要實現此接口定義的五個方法addEventListener

、dispatchEvent、willTrigger、removeEventListener和hasEventListener。當然,

在實現過程中,可以靈活地添加別的新特性。

二、事件流機制
(1)、捕獲階段:Flash Player會按照顯示列表,從根容器舞臺往下找,直到確定是哪

個桌的客人在喊話要菜。
(2)、目標階段:捕獲階段結束時停在哪個目標對象上。
(3)、冒泡階段:事件對象從目標對象再次沿顯示列表往上移動至根容器舞臺,遇到注

冊偵聽的節點就調用偵聽函數。如果想中途中斷冒泡,可以使用stopPropagation,詳

見文末Event備註部分。
一些細節:
(1)、這三個階段由Event中的eventPhase屬性來記錄,1表示捕獲,2表示目標,3表示

冒泡。
(2)、目標階段確定的目標對象由Event中的target屬性來記錄,冒泡階段移動的遊標

則由currentTarget來記錄。事件對象每往上移動一級,就會克隆出一個僅與前副本

currentTarget不同的新副本。這也提示我們,在自定義Event類時,如果打開了冒泡

屬性bubbles,則必須要覆蓋原有的clone方法,否則在冒泡時就會丟失自定義的存儲

數據。同樣,最好也覆蓋原有的toString方法。
(3)、偵聽器的調用一般發生在冒泡階段。但是當target等於currentTarget,也就是

當前偵聽對象就是事件發生對象時,冒泡階段就沒有了,這時目標階段就發生了偵聽

器調用。如果希望在捕獲階段偵聽事件,將addEventListener中的useCapture參數改

爲true即可,這時冒泡階段將不再發生偵聽。如果希望仍在冒泡階段繼續偵聽,需要

新添加一個useCapture爲默認值false的偵聽。
(4)、事件對象是否可以冒泡要看兩點:第一,事件本身是否支持冒泡,由bubbles屬

性設定,爲true則支持,默認爲false;第二,如果事件發生的對象不在顯示列表中,

也不可能冒泡,此時只有目標階段,如Timer和URLLoader。
(5)、顯示列表下,某個容器中有兩個並列子節點1和2。如果子節點1發出事件,需要

在子節點2中進行偵聽,默認情況下是做不到的。常用的一種辦法是向子節點1和子節

點2都傳入一個相同的對象的實例,在子節點1中用這個對象實例發出事件,在子節點2

中用這個對象實例監聽事件(在目標階段捕獲事件)。這樣就可以收到字節點1的事件

了。

三、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  是否可以停止
)

方法:
isDefaultPrevented:判斷preventDefault 是否已經被調用
preventDefault:停止事件的默認行爲。針對一些系統事件,cancelable爲true時才

可用。 
stopImmediatePropagation:停止當前的事件流傳播,包括當前正在處理的對象 
stopPropagation:停止當前的事件流傳播,但不會停止當前正在處理的對象

四、偵聽器備註

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

默認情況下,Flex會按照監聽器註冊的順序來調用監聽函數。使用addEventListener

函數的priority 來實現 監聽函數的優先級。priority 爲整數類型,數字越大,級別

越高。級別最高的最先被調用。已經存在的監聽器,無法被修改優先級。使用MXML添

加的事件監聽函數無法指定優先級別,將採用默認的級別。給一個對象註冊多個監聽

器,即使每個監聽器的優先級別不同,但也無法保證後一個執行時前面的監聽函數已

經執行完畢。設計時,後面的函數不應該以前者執行完畢爲條件。

 

 

 

更多詳情請點擊  http://blog.sina.com.cn/zhaojianjunzjj

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