深度探索as3的事件机制

 

as3的事件机制很好用了。但要用好,用对,就得详细了解它的事件模型。本文将深度探索as3事件的各个方面

  • 事件模型
  • as3的事件系统包括 dispatchers(派发器),listeners(监听器)和event object(事件对象)。它们的关系用一句话概括:dispatchers向已注册的listeners派发event object。具体的关系图可以参考下面的图

     

  • 冒泡机制
  • as3的事件过程包括三个阶段 捕获,目标和冒泡阶段。下面我举一个很简单的例子来说明。舞台stage上有一个元件mc,mc上有一个子按钮元件btn。现在点击btn,发生了什么事呢?看下图

    捕获阶段:鼠标在btn上发出点击事件。首先捕获该事件的是stage,然后向下传递到mc,再到btn
    目标阶段:找到鼠标的最底层的目标btn,如果它注册了监听函数,就执行该监听函数了
    冒泡阶段:开始冒泡,自底向上。从btn到mc,最后到stage

     

    mc.addEventListener(MouseEvent.CLICK,onClickMc);
    mc.btn.addEventListener(MouseEvent.CLICK,onClickBtn);
    function onClickMc(event:MouseEvent) {
            trace("点击mc");
    }
    function onClickBtn(event:MouseEvent) {
            trace("点击btn");
    }

     

    执行结果:
    点击btn
    点击mc

     

  • addEventListener的参数
  • 我们通常只用了前面两个参数,后面的都是默认参数。下面详细讨论一下
    第三个参数 useCapture
    “确定侦听器是运行于捕获阶段、目标阶段还是冒泡阶段。如果将 useCapture 设置为 true,则侦听器只在捕获阶段处理事件,而不在目标或冒泡阶段处理事件。如果 useCapture 为 false,则侦听器只在目标或冒泡阶段处理事件。要在所有三个阶段都侦听事件,请调用 addEventListener 两次:一次将 useCapture 设置为 true,一次将 useCapture 设置为 false.”

    第四个参数 priority优先级
    默认是0.可以设置成任意的整数。当你为同一个事件监听了两个处理函数,设置不同的优先级,就可以决定他们被处理的顺序了

    第五个参数 useWeekReference 是否弱引用
    决定监听器的引用是否弱引用。如果是弱引用,当listener只剩下这一个弱引用的时候,GC就可以回收了

  • target和currentTarget的区别
  • 先来看看它们的定义。target是事件的调用者(event dispatcher)。currentTarget是事件的处理者。

    在一般情况下,两者指向的是同一对象。例如我们对某个单独的mc监听鼠标点击事件。在MouseEvent.CLICK处理函数中 target和currentTarget是同一个对象
    现在来看看不同的情况。有两个元件 m1和m2,m2是m1的子元件。给m1监听鼠标点击事件。
    现在点击m1(不包括m2)的部分,处理函数中显示:target和currentTarget均指向父容器m1。
    点击m2,处理函数中显示 target指向m2,currentTarget指向m1。

    这是为什么呢?因为as3的事件处理默认是采用冒泡机制的。currentTarget应该先指向低层,再向上冒泡。
    小结一下:target一般来说都是最里层的对象。currentTarget则是注册监听器的对象,一般是容器

  • 阻止冒泡
  • 冒泡机制是很有好处了,但是我们有时要阻止冒泡。as3也提供了阻止冒泡的机制
    1.stopImmediatePropagation():void
    防止对事件流中当前节点中和所有后续节点中的事件侦听器进行处理。

    2.stopPropagation():void
    防止对事件流中当前节点的后续节点中的所有事件侦听器进行处理。

    两者的区别在于是否阻止当前节点?处理到当前节点了,还要阻止当前节点?头脑有些转不过弯吧。当你为同一个对象的同一个事件监听处理时,这个功能就有用了。处理了第一个监听函数,调用stopImmediatePropagation()。其他的监听函数就无法收到事件了

  • 自定义事件
  • 很简单,继承Event就行啦。如果可能,顺便重新clone和toString函数,因为派发事件的事件的时候会自动调用

  • 自定义事件派发器
  • 也很简单,继承EventDispatcher就行了,或者实现IEventDispatcher接口

  • 还有
  • 不是所有的事件都有这三个阶段。如Timer、URLLoader,它们的事件对象将直接派送给目标对象(target).它们只包含目标阶段而没有捕获阶段和冒泡阶段。因为她们根本不需要显示列表

     

    你可能感兴趣的:(Flash,事件机制,as3)