如何实现Flex3中AS2和AS3之间事件转换
这篇文章主要介绍如何实现Flex3中AS2和AS3之间事件转换,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
事件的转换
AS3的事件与AS2有很大的不同,形势更统一,功能更强大。
1.监听事件的方式(Handlingtheevents)
在AS2时代,有几种监听事件的方式,比如onPress=function(){},addListener(listener)等等,而AS3时代,统一用一种addEventListener(type:String,listener:Function,useCapture:Boolean=false,priority:int=0,useWeakReference:Boolean=false):void,这是接口IEventDispatcher申明的一个方法,EventDispatcher类实现了这个方法(当然还实现了若干其他方法,这里不尽述),这里举个监听元件被按下的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属性,让他调用__onPress,而AS3是增加一个监听,并没有覆盖什么。说明AS3更灵活,因为如果你有两个监听器,AS2会很难处理。其次,AS2中为了使得监听函数的作用域(scope)能正确(即是说函数里面的this要能正确的指到本实例),通常我们需要用Delegate。而AS3中,不需要使用它,因为AS3对于函数操作会自动进行Delegate,相当于系统或者编译器帮我们调用了Delegate,由此省去了麻烦,避免了忘记调用而引入的错误。AS3中的每个事件监听函数都必须接受一个事件实例(Evnetinstance,这将在下一节介绍。
另外,这里看看addEventListener的其他几个参数,useCapture是否用在捕获时期,这个在第三节会讲解;priority优先度,同一个类型的事件,优先度越大的监听器,会越早被调用,默认值为0;useWeakReference是否是弱引用,AS3加入了弱引用的功能,熟悉Java的朋友因该知道这是什么含义,即是指这次引用不会计算到引用计数中,垃圾回收器会在一个对象没有被任何其他对象强引用的时候,把它回收掉。也就是说,如果这里你用了useWeakReference=true,那么这个监听器如果没有别的地方存在对它的引用的时候,就会被回收,不过通常我们都用默认值false,因为严格管理的程序,你会自己记得什么时候加监听,什么时候移除监听的。
◆在AS2时代,移除监听器,对于上面的例子很简单,只需要简单的mc.onPress=undefined即可,在AS3中,需要这样mc.removeEventListener(MouseEvent.MOUSE_DOWN,__onPress),其实也很方便,你移除刚刚增加的监听,只需要把addEventListener函数替换为removeEventListener函数,前三个参数保持不变(我这里的例子第三个参数都用了缺省值)。
AS2中,还有其他监听事件的方法,比如Key.addListener这样的方式,这和AS3的方式有点相似,不同之处在于它是加入object作为监听器,然后调用object的指定名称的方法,因此它很动态,易出错,比如我把object的onKeyDown方法写成了onkeydown,编译器不会报任何错误,但是程序运行的时候,可能就不是你想要的效果。
2.事件类(Eventclasses)
前面我们提到了,AS3的事件监听函数都必须接收一个事件对象,不同的事件可能会接收不同类型的对象(具体是什么类型,请详查帮助文档),但是所有事件类都继承自flash.events.Event类。Flex3教程中不同的事件类型都有他们各自的属性、方法,你可以从这些属性方法得到你想要的事件内容。比如MouseEvent.stageX让你知道鼠标事件发生时鼠标在舞台上的x坐标,KeyboardEvent.keyCode让你知道键盘事件发生时的按下/释放的按键码。
有很多属性、方法是与事件流相关的,因此我们放入下一节讲解。
3.事件流(Eventflow)
Flex3教程中事件流是AS3引入的新机制,它让可视元素的事件监听更灵活强大。
事件上事件流只对可视元素有效,也就说DisplayObject对象和其子类对象才拥有此机制。究竟什么是事件流呢?
事件流是指一个事件不光是触发自己的监听器,它还会触发自己父元件到舞台整个路径中的其他节点的同类监听器,顺序是这样的:***阶段(Capture阶段)事件从stage到发生者的父元件路径中所有元件依次触发事件,然后第二阶段(Target阶段)事件发生者自己触发,***第三阶段(Bubbling阶段),事件从发生者父类再回溯到stage依次触发。如下图所示:
注意这里的Flow,是指舞台上的元件层次结构中的流,对应于DisplayObject.parent和DisplayObjectContainer.getChildAt()所相关的一个结构。注意这并不是类继承关系的结构。在接触AS3的初期,这比较难以理解透,这里我举个例子,应该能够使得你更好理解:
在AS2时代,假设我要做一个简单的窗口,这个窗口上面只放置了一个确定按纽,我们设想的功能是,首先这个窗口可以被拖动,然后用户点击确定按纽则关闭这个窗口。那么通常,简单地我们会创建一个MC作为窗体,然后这个MC里面创建一个Button,监听Button的onPress事件来关闭MC,这时没问题,然后拖动MC的实现,我们通过监听MC的onPress事件来startDrag,问题出现了,由于Button在MC内,因此MC监听了事件后,Button就接收不到事件了。通常为此,我们得创建一个背景元件放在那个MC里面,Button的下面,然后监听那个背景元件的事件来启动拖动。这样要创建这个多余的背景元件原因就是,如果一个元件的父元件监听了事件(这里指鼠标事件,有的事件是不同的),那么这个元件将不会监听到任何事件。
相当于说父元件吃掉了所有子元件的事件。而AS3里面,就不同了,回想一下刚才介绍的事件流的过程,如果用户点击了Button,首先会是stage会触发事件,然后是MC的父元件们,然后是MC,然后是Button,然后再反向循环一次。如果用户点击了MC(比如Button旁边,MC内),则会是stage->MC父元件->MC->MC父元件->stage,两种情况,MC都会得到事件触发,因此,在AS3时代,再也不需要创建多余的专门用来监听事件的辅助元件了。代码也会变得简单。并且capture和bubling阶段的不同顺序,可以让你选择是先于事件触发者做动作,还是后于它做动作。addEventListener(type:String,listener:Function,useCapture:Boolean=false,priority:int=0,useWeakReference:Boolean=false):void方法的第三个参数,让你可以指定是否是监听capture阶段的事件,false代表监听其他两个阶段的事件。在removeEventListener方法中,你要指定要移除的监听器是哪个阶段的,缺省值是false。
◆相对于事件流,Flex3教程中Event类有一系列与之相关的属性和方法:
target:此属性指向事件触发者,比如刚才的例子,鼠标点击了Button,那么这个target就是Button,如果鼠标点击了Button旁边,MC内,那么它就是MC。
currentTarget:此属性指向事件流中,当前触发事件的元件。比如刚才的例子,鼠标点击了Button,如果你监听了MC的鼠标点击事件,那么在监听MC的监听器里面,这个currentTarget就指向MC,而在监听Button的监听器里面,这个currentTarget指向Button。你可以看看事件流的那个图,currentTarget实际上值的顺序依次是Stage->ParentNode->Child1Node->ParentNode->Stage。比较起target,对于每个事件,target则始终是指事件发生者,比如图中的Child1Node。
bubbles:此属性表示此事件在事件流中是否有bubbling阶段,有的事件是没有这一阶段的,比如unload事件,大部分非交互性事件也都没有bubbling阶段。所有事件都拥有capture阶段吗?前面讲过了,只有可视元素才拥有事件流的概念,也就是说非可视元素是不可能拥有capture和bubbling阶段的。那所有元件的事件,都拥有capture阶段?对,是这样的,bubbles为false的事件虽无bubbles阶段,但有capture阶段。
cancelable:此属性表示此事件是否可以取消它的默认行为。此属性与preventDefault()方法相关。
eventPhase:此属性表示此事件处于事件流中的哪个阶段,capture,target,bubbling三种阶段之一。
type:此属性表示此事件是什么类型,这个属性与addEventListener/removeEventListener的***个参数type:String对应。
preventDefault():此方法取消事件的默认行为,并不是所有事件都有默认行为,也并不是所有事件的默认行为都可以取消。一个事件的默认行为是否可取消,可以通过cancelable属性得知。这里举个例子,TextEvent.TEXT_INPUT事件的默认行为是把输入的字符加入到TextField中,此事件行为可以取消,如果你调用它的preventDefault()方法,那么字符就不会加入到TextField中。而MouseEvent.MOUSE_DOWN这样的事件,就没有可取消的默认行为,比如你按下一个按钮,已经行为已经发生,不能取消,实际上这个行为在逻辑上看,也没有什么可取消的东西,看你怎样理解了,反正可否取cancelable已经表明。
isDefaultPrevented():此方法返回事件的默认行为是否已经被取消了。
stopPropagation():此方法可停止事件在事件流中的传播,比如上面提到的例子,假如你在capture阶段stage监听器里面调用了此方法,那么后面的节点中,都不会收到事件了。如果你在中途调用此函数,那么此函数执行后,后面的节点阶段,不会收到事件。
stopImmediatePropagation():此方法可停止事件在事件流包括当前节点中的传播,此方法与stopPropagation()的区别之处在于,stopPropagation()不会停止当前节点的事件触发,你知道,我们可以给同一个节点,比如stage加入多个监听器,如果采用stopPropagation(),那么在你调用了它之后,同节点的监听器被触发完全之后,事件停止传播。而stopImmediatePropagation()会在它被调用后立即停止传播,即使是同节点的事件,也将收不到事件。
以上是"如何实现Flex3中AS2和AS3之间事件转换"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!