這篇文章主要介紹如何實現(xiàn)Flex3中AS2和AS3之間事件轉(zhuǎn)換,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供昭平網(wǎng)站建設(shè)、昭平做網(wǎng)站、昭平網(wǎng)站設(shè)計、昭平網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、昭平企業(yè)網(wǎng)站模板建站服務(wù),十載昭平做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
事件的轉(zhuǎn)換
AS3的事件與AS2有很大的不同,形勢更統(tǒng)一,功能更強大。
1.監(jiān)聽事件的方式(Handlingtheevents)
在AS2時代,有幾種監(jiān)聽事件的方式,比如onPress=function(){},addListener(listener)等等,而AS3時代,統(tǒng)一用一種addEventListener(type:String,listener:Function,useCapture:Boolean=false,priority:int=0,useWeakReference:Boolean=false):void,這是接口IEventDispatcher申明的一個方法,EventDispatcher類實現(xiàn)了這個方法(當(dāng)然還實現(xiàn)了若干其他方法,這里不盡述),這里舉個監(jiān)聽元件被按下的AS2,AS3方法對照的例子:
AS2:
mc.onPress=Delegate.create(this,__onPress); ... privatefunction__onPress():Void{ //Dosomething } AS3: mc.addEventListener(MouseEvent.MOUSE_DOWN,__onPress); ... privatefunction__onPress(e:MouseEvent):Void{ //Dosomething }
可以看出,首先不同的地方是AS2直接覆蓋了onPress屬性,讓他調(diào)用__onPress,而AS3是增加一個監(jiān)聽,并沒有覆蓋什么。說明AS3更靈活,因為如果你有兩個監(jiān)聽器,AS2會很難處理。其次,AS2中為了使得監(jiān)聽函數(shù)的作用域(scope)能正確(即是說函數(shù)里面的this要能正確的指到本實例),通常我們需要用Delegate。而AS3中,不需要使用它,因為AS3對于函數(shù)操作會自動進行Delegate,相當(dāng)于系統(tǒng)或者編譯器幫我們調(diào)用了Delegate,由此省去了麻煩,避免了忘記調(diào)用而引入的錯誤。AS3中的每個事件監(jiān)聽函數(shù)都必須接受一個事件實例(Evnetinstance,這將在下一節(jié)介紹。
另外,這里看看addEventListener的其他幾個參數(shù),useCapture是否用在捕獲時期,這個在第三節(jié)會講解;priority優(yōu)先度,同一個類型的事件,優(yōu)先度越大的監(jiān)聽器,會越早被調(diào)用,默認(rèn)值為0;useWeakReference是否是弱引用,AS3加入了弱引用的功能,熟悉Java的朋友因該知道這是什么含義,即是指這次引用不會計算到引用計數(shù)中,垃圾回收器會在一個對象沒有被任何其他對象強引用的時候,把它回收掉。也就是說,如果這里你用了useWeakReference=true,那么這個監(jiān)聽器如果沒有別的地方存在對它的引用的時候,就會被回收,不過通常我們都用默認(rèn)值false,因為嚴(yán)格管理的程序,你會自己記得什么時候加監(jiān)聽,什么時候移除監(jiān)聽的。
◆在AS2時代,移除監(jiān)聽器,對于上面的例子很簡單,只需要簡單的mc.onPress=undefined即可,在AS3中,需要這樣mc.removeEventListener(MouseEvent.MOUSE_DOWN,__onPress),其實也很方便,你移除剛剛增加的監(jiān)聽,只需要把addEventListener函數(shù)替換為removeEventListener函數(shù),前三個參數(shù)保持不變(我這里的例子第三個參數(shù)都用了缺省值)。
AS2中,還有其他監(jiān)聽事件的方法,比如Key.addListener這樣的方式,這和AS3的方式有點相似,不同之處在于它是加入object作為監(jiān)聽器,然后調(diào)用object的指定名稱的方法,因此它很動態(tài),易出錯,比如我把object的onKeyDown方法寫成了onkeydown,編譯器不會報任何錯誤,但是程序運行的時候,可能就不是你想要的效果。
2.事件類(Eventclasses)
前面我們提到了,AS3的事件監(jiān)聽函數(shù)都必須接收一個事件對象,不同的事件可能會接收不同類型的對象(具體是什么類型,請詳查幫助文檔),但是所有事件類都繼承自flash.events.Event類。Flex3教程中不同的事件類型都有他們各自的屬性、方法,你可以從這些屬性方法得到你想要的事件內(nèi)容。比如MouseEvent.stageX讓你知道鼠標(biāo)事件發(fā)生時鼠標(biāo)在舞臺上的x坐標(biāo),KeyboardEvent.keyCode讓你知道鍵盤事件發(fā)生時的按下/釋放的按鍵碼。
有很多屬性、方法是與事件流相關(guān)的,因此我們放入下一節(jié)講解。
3.事件流(Eventflow)
Flex3教程中事件流是AS3引入的新機制,它讓可視元素的事件監(jiān)聽更靈活強大。
事件上事件流只對可視元素有效,也就說DisplayObject對象和其子類對象才擁有此機制。究竟什么是事件流呢?
事件流是指一個事件不光是觸發(fā)自己的監(jiān)聽器,它還會觸發(fā)自己父元件到舞臺整個路徑中的其他節(jié)點的同類監(jiān)聽器,順序是這樣的:***階段(Capture階段)事件從stage到發(fā)生者的父元件路徑中所有元件依次觸發(fā)事件,然后第二階段(Target階段)事件發(fā)生者自己觸發(fā),***第三階段(Bubbling階段),事件從發(fā)生者父類再回溯到stage依次觸發(fā)。如下圖所示:
注意這里的Flow,是指舞臺上的元件層次結(jié)構(gòu)中的流,對應(yīng)于DisplayObject.parent和DisplayObjectContainer.getChildAt()所相關(guān)的一個結(jié)構(gòu)。注意這并不是類繼承關(guān)系的結(jié)構(gòu)。在接觸AS3的初期,這比較難以理解透,這里我舉個例子,應(yīng)該能夠使得你更好理解:
在AS2時代,假設(shè)我要做一個簡單的窗口,這個窗口上面只放置了一個確定按紐,我們設(shè)想的功能是,首先這個窗口可以被拖動,然后用戶點擊確定按紐則關(guān)閉這個窗口。那么通常,簡單地我們會創(chuàng)建一個MC作為窗體,然后這個MC里面創(chuàng)建一個Button,監(jiān)聽Button的onPress事件來關(guān)閉MC,這時沒問題,然后拖動MC的實現(xiàn),我們通過監(jiān)聽MC的onPress事件來startDrag,問題出現(xiàn)了,由于Button在MC內(nèi),因此MC監(jiān)聽了事件后,Button就接收不到事件了。通常為此,我們得創(chuàng)建一個背景元件放在那個MC里面,Button的下面,然后監(jiān)聽那個背景元件的事件來啟動拖動。這樣要創(chuàng)建這個多余的背景元件原因就是,如果一個元件的父元件監(jiān)聽了事件(這里指鼠標(biāo)事件,有的事件是不同的),那么這個元件將不會監(jiān)聽到任何事件。
相當(dāng)于說父元件吃掉了所有子元件的事件。而AS3里面,就不同了,回想一下剛才介紹的事件流的過程,如果用戶點擊了Button,首先會是stage會觸發(fā)事件,然后是MC的父元件們,然后是MC,然后是Button,然后再反向循環(huán)一次。如果用戶點擊了MC(比如Button旁邊,MC內(nèi)),則會是stage->MC父元件->MC->MC父元件->stage,兩種情況,MC都會得到事件觸發(fā),因此,在AS3時代,再也不需要創(chuàng)建多余的專門用來監(jiān)聽事件的輔助元件了。代碼也會變得簡單。并且capture和bubling階段的不同順序,可以讓你選擇是先于事件觸發(fā)者做動作,還是后于它做動作。addEventListener(type:String,listener:Function,useCapture:Boolean=false,priority:int=0,useWeakReference:Boolean=false):void方法的第三個參數(shù),讓你可以指定是否是監(jiān)聽capture階段的事件,false代表監(jiān)聽其他兩個階段的事件。在removeEventListener方法中,你要指定要移除的監(jiān)聽器是哪個階段的,缺省值是false。
◆相對于事件流,F(xiàn)lex3教程中Event類有一系列與之相關(guān)的屬性和方法:
target:此屬性指向事件觸發(fā)者,比如剛才的例子,鼠標(biāo)點擊了Button,那么這個target就是Button,如果鼠標(biāo)點擊了Button旁邊,MC內(nèi),那么它就是MC。
currentTarget:此屬性指向事件流中,當(dāng)前觸發(fā)事件的元件。比如剛才的例子,鼠標(biāo)點擊了Button,如果你監(jiān)聽了MC的鼠標(biāo)點擊事件,那么在監(jiān)聽MC的監(jiān)聽器里面,這個currentTarget就指向MC,而在監(jiān)聽Button的監(jiān)聽器里面,這個currentTarget指向Button。你可以看看事件流的那個圖,currentTarget實際上值的順序依次是Stage->ParentNode->Child1Node->ParentNode->Stage。比較起target,對于每個事件,target則始終是指事件發(fā)生者,比如圖中的Child1Node。
bubbles:此屬性表示此事件在事件流中是否有bubbling階段,有的事件是沒有這一階段的,比如unload事件,大部分非交互性事件也都沒有bubbling階段。所有事件都擁有capture階段嗎?前面講過了,只有可視元素才擁有事件流的概念,也就是說非可視元素是不可能擁有capture和bubbling階段的。那所有元件的事件,都擁有capture階段?對,是這樣的,bubbles為false的事件雖無bubbles階段,但有capture階段。
cancelable:此屬性表示此事件是否可以取消它的默認(rèn)行為。此屬性與preventDefault()方法相關(guān)。
eventPhase:此屬性表示此事件處于事件流中的哪個階段,capture,target,bubbling三種階段之一。
type:此屬性表示此事件是什么類型,這個屬性與addEventListener/removeEventListener的***個參數(shù)type:String對應(yīng)。
preventDefault():此方法取消事件的默認(rèn)行為,并不是所有事件都有默認(rèn)行為,也并不是所有事件的默認(rèn)行為都可以取消。一個事件的默認(rèn)行為是否可取消,可以通過cancelable屬性得知。這里舉個例子,TextEvent.TEXT_INPUT事件的默認(rèn)行為是把輸入的字符加入到TextField中,此事件行為可以取消,如果你調(diào)用它的preventDefault()方法,那么字符就不會加入到TextField中。而MouseEvent.MOUSE_DOWN這樣的事件,就沒有可取消的默認(rèn)行為,比如你按下一個按鈕,已經(jīng)行為已經(jīng)發(fā)生,不能取消,實際上這個行為在邏輯上看,也沒有什么可取消的東西,看你怎樣理解了,反正可否取cancelable已經(jīng)表明。
isDefaultPrevented():此方法返回事件的默認(rèn)行為是否已經(jīng)被取消了。
stopPropagation():此方法可停止事件在事件流中的傳播,比如上面提到的例子,假如你在capture階段stage監(jiān)聽器里面調(diào)用了此方法,那么后面的節(jié)點中,都不會收到事件了。如果你在中途調(diào)用此函數(shù),那么此函數(shù)執(zhí)行后,后面的節(jié)點階段,不會收到事件。
stopImmediatePropagation():此方法可停止事件在事件流包括當(dāng)前節(jié)點中的傳播,此方法與stopPropagation()的區(qū)別之處在于,stopPropagation()不會停止當(dāng)前節(jié)點的事件觸發(fā),你知道,我們可以給同一個節(jié)點,比如stage加入多個監(jiān)聽器,如果采用stopPropagation(),那么在你調(diào)用了它之后,同節(jié)點的監(jiān)聽器被觸發(fā)完全之后,事件停止傳播。而stopImmediatePropagation()會在它被調(diào)用后立即停止傳播,即使是同節(jié)點的事件,也將收不到事件。
以上是“如何實現(xiàn)Flex3中AS2和AS3之間事件轉(zhuǎn)換”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!