as3事件流機制徹底理解

as3和dom的事件流都分三個階段:捕獲階段、目標階段、冒泡階段。如果記不住這三個階段的順序,想象以下捕魚的過程,捕魚也分三個階段:撒網、捕捉,撈起,三個階段從上向下。


爲什麼要事件流要分三個階段呢?


這一切都是因爲“顯示列表”,沒有顯示列表,也就不會有事件流。在顯示列表中,假設,s:舞臺;c:容器;b:按鈕。


點擊按鈕b,b應該發出click事件,這沒錯。從常識上來說,點擊了b,也就間接點擊了c吧,因爲c包含b,那麼c也應該發出click事件,同理s也應該發出click事件。問題就來了,s、c、b發出click事件的順序該如何處理?


用盒子模型來理解,要想“摸東西”,肯定要從最外層的盒子開始摸起,層層向內摸,所以事件流的第一階段是捕獲階段,由外至內。接着就是目標階段。摸完東西,手就要縮回來,縮回來的過程就是冒泡階段。


捕獲階段和目標階段我們很容易理解,從外向內依次發出事件,那爲什麼還要有冒泡階段呢?冒泡階段是爲了滿足用戶靈活處理事件的需求而產生的。只有捕獲和目標階段,那麼用戶就必須先處理s的click事件,然後是c的click事件,最後纔是b。但好多時候,用戶是想先處理b的click事件,然後纔是c,最後是s,冒泡階段由此而生。


addEventListener(type:String, listener:Function, useCapture:Boolean= false, priority:int= 0, useWeakReference:Boolean= false):void

用addEventListener監聽事件,默認是目標階段或者冒泡階段,只有useCapture=true的時候,纔是捕獲階段。b只有目標階段,s和c有捕獲和冒泡兩個階段。


function onClick(e:MouseEvent):void

{

    trace(e.target);

    trace(e.currentTarget);

}


b.addEventListener(MouseEvent.CLICK, onClick,  false); //e.target == e.currentTarget == b

b.addEventListener(MouseEvent.CLICK, onClick,  true); //不會有任何效果。


c.addEventListener(MouseEvent.CLICK, onClick,  false); //e.target ==  b,e.currentTarget == c

c.addEventListener(MouseEvent.CLICK, onClick,  true); //e.target ==  b,e.currentTarget == c


s.addEventListener(MouseEvent.CLICK, onClick,  false); //e.target ==  b,e.currentTarget == s

s.addEventListener(MouseEvent.CLICK, onClick,  true); //e.target ==  b,e.currentTarget == s


注意,假如b.mouseChildren=false; b.mouseEnabled=false; 那麼c的click事件中e.target ==  c。因此,InteractiveObject.mouseEnabled==true的時候,通過事件流使父容器發出事件的,InteractiveObject.mouseEnabled==false的時候,跟非InteractiveObject一樣,是通過填充父容器,使父容器直接發出事件。


記住,事件流因顯示列表而生,像捕魚一樣有三個階段:捕獲、目標、冒泡。

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