所以当监听MouseEvent.ROLL_OVER事件后,鼠标移动到panel的几个按钮时,程序仍然认为鼠标悬停在panel上方。假设我们监听MouseEvent.MOUSE_OVER, 随着鼠标移到panel的按钮上,程序立刻判断鼠标离开了panel,已经到了按钮上方——这个结果不是我们需要的,此时本应去单击按钮,结果程序判断鼠标离开panel,会直接removeChild或者visible=false。
关于冒泡的话,不得不提AS3的事件流,简单的说就是一个捕捉——目标——冒泡的循环过程:事件发生后,先从显示层中的根容器开始往下层级逐个捕捉直至到达派发事件的目标对象后向上返回冒泡,而这一事件中的target属性始终指向最内层的派发事件目标,currentTarget则顾名思义指向事件流中当前所在的对象。
事件发生后,从根节点到目标节点的父节点,这中间所有节点都有两次机会可以响应事件,分别在捕获和冒泡阶段。在事件流经过的任意节点上注册侦听器都会触发。当然前提是打开了捕获和冒泡功能。
默认情况下,捕获功能处于关闭状态,因为实际开发中,监听目标很明确,没必要捕获。
而事件只有在bubbles属性为true时才进行冒泡,默认冒泡的事件包括:change,click,doubleClick,keyDown,keyUp,mouseDown,mouseUp。一旦捕获打开,默认的冒泡将被取消。
因此在同一个监听器中不能同时打开捕获和冒泡,只能注册两个监听一个开捕获一个开冒泡才行。
只有可视化对象(容器,控件)才有捕获和冒泡阶段,而像XML,WebService等非可视化对象只有目标阶段。
注册侦听器方法为:
addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false)
useCapture即为是否打开捕获功能,
priority为优先级设定,当有多个侦听器时,priority越大,优先级越高越先调用,如果同级的话则按注册的顺序来调用。这里注意即使优先级有先后也无法保证后一个侦听调用执行时前一个侦听函数已执行完毕。
useWeakReference为弱引用开关,推荐设为true,便于垃圾自动回收。但最规范的还是直接removeEventListener。注意当注册监听器打开了捕获,则removeEventListener(type:String, listener:Function, useCapture:Boolean=false)的useCapture必须设为true,否则无效
事件对象的构造方法为:
Event(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
bubbles即为是否冒泡
cancelable为true时可以调用PreventDefault方法停止系统默认的行为。比如输入文本,默认行为会马上显示在文本区,当cancelable为true时调用PreventDefault方法让字符不出现。
另外,Event还有两个方法可以停止事件流的继续传播,stopPropagation和stopImmediatePropagation,区别在于前者不会停止正在处理的对象。而后者还会停止同一object上的其他侦听器。