`
ahead_zhan
  • 浏览: 27713 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

深入理解FLEX事件机制

    博客分类:
  • Flex
阅读更多

 

1.  AS3中的事件为什么要分三个阶段,即捕获、目标、冒泡。

这要从FLEX使用的脚本语言ActionScript3的老大哥Javascript说起,熟悉Javascript的朋友都知道在DOM中完整的事件生命周期包括捕获、目标与冒泡三个阶段。
事件的处理过程将从事件目标所在DOM层次的根节点开始,而不是从派发事件的目标开始,并且最终会回到根节点。

捕获阶段:事件从目标所在DOM树的根节点依次往下层传递,一直到目标节点之前的过程。在这个过程中,事件将会被从根节点到事件目标之前的所有父节点对象所捕获。如果事件在被注册时设置了useCapture属性为true,那么它会被这期间的所有注册了该事件的父元素对象依次派发。

目标阶段:事件到达目标元素。目标元素如果注册了该事件并且设置了useCapture属性为false,则目标会派发该事件。

冒泡阶段:事件到达目标元素后会接着通过DOM节点向上层父节点冒泡,并最终回到目标所在DOM树的根节点的过程。在这个过程中如果事件是可冒泡事件(最典型的例子就是click事件)并且在被注册时设置了useCapture属性为false,那么它会被这期间的所有注册了该事件的父元素对象派发。

AS3也采用这套机制。上图就是Adobe官方文档中的插图。真个AS3事件的生命周期与DOM对象上JS事件的生命周期完全相同。
我认为这套机制这样最大的好处就是可以减少了同一个UI树上对象监听器数量,从而带来性能优化。

举个简单而常见的例子:
canvas上有n个button,如果给每个button注册一个click事件,那么内存中就需要维护n个listener。由于click事件是可冒泡事件,那么更好的解决办法就是给canvas注册一个click事件,即

canvas.addEventListener(MouseEvent.CLICK, onMouseClickHandler);

调通过事件的冒泡阶段由n个button共同的父元素canvas来派发click事件,并且可以通过事件参数的target属性来决定调用哪个button对应的处理函数。这样做的的好处就可以只注册一个事件监听从而代替为n个button注册n个事件。

2.target和currentTarget究竟谁是事件的派发者?

target:事件指向的目标,但并非事件的派发者。 在一个事件整个生命周期中所有被派发的事件处理函数内部的target对象是一样的,每个被监听者派发的事件处理函数中的target一定都是同一个对象。
currentTarget:事件的派发者。调用注册在事件上的回调函数的那个对象,简单的说就是派发事件的对象。

3.useCapture到底有何用?

 

首先看看AS3中为IEventDispatcher类型对象注册事件监听的接口(完全符合W3C标准)

 

 

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

 

 

 

最显而易见的用处,如果没有这个参数,那么走完事件的生命周期,所有目标父节点上注册的事件都会被执行两次(捕获阶段一次+冒泡阶段一次)!也正因为有useCapture这个参数,整个事件机制的运作才有了分支,或者更说是被分成两个独立部分。

拿上面“n个button的例子”来说,如果用户点击某一个button将会触发click事件,首先我们来看下整个click事件的生命周期中将会经历的UI对象:

stage → canvas → button →  canvas → stage

然后我们再看分析一下事件流的三个阶段。
首先是捕获阶段:
事件从该button所处显示对象树的根出发,也就是stage,stage上未注册click事件,不会做出任何响应。
然后来到stage的子节点即canvas,注意我们在canvas上注册了click事件,而此时click事件不会被派发,因为例子中我们注册的click事件使用的是默认的useCapture=false参数,即click事件必须在目标和冒泡阶段才能被派发。
然后进入目标阶段:
尽管目标是button,但由于其并未注册任何click事件监听所以也不作出任何响应。
由于click事件是可冒泡事件,所以最后会进入冒泡阶段:
从button到canvas,canvas上注册了click事件监听,所以canvas派发该事件,进入事件处理函数,此时target是button,currentTarget是canvas。

如果useCapture=true呢?
还是“n个button的例子”,我们给canvas注册一个useCapture=true的click事件会怎么样呢即

canvas.addEventListener(MouseEvent.CLICK, onMouseClickHandler, true);

 

这样有三点好处:

1. 事件不会经历目标和捕获阶段,这样只有当且仅当事件的target为监听对象的子对象时,事件才会被派发。“n个button的例子”当监听器的参数useCapture=true,用户点击目标如果是canvas自己,则事件不会被派发。换言之只有点击canvas上的子对象,比如某个button或是canvas上的其他UIcomponent,click事件才会触发。再解释一遍为什么吧。点击canvas本身,事件流首先进入捕获阶段从目标(canvas)所在显示对象列表的根stage开始向下,来到canvas上,这时因为event.target==canvas,进入目标阶段,尽管canvas注册了click事件,但useCapture参数是true,那就是说事件只能在捕获阶段被派发,所以这个事件并不会被派发出来,也就是点击canvas没有任何响应。
想象一下应用场景,比如那种点击小球会得分的游戏,我们可以给小球的容器对象加上监听,但又不想在事件处理函数中接判断用户是否点到了容器本身上,这时我们大可放心的给容器对象加上useCapture=true的点击事件监听,让事件在捕获阶段就派发出来,这样就再也不用在函数中check来check去了,管它event.target是谁呢。
2. 不用考虑事件是否支持冒泡。
3. 由于少了两个阶段,必然少折腾一些传递。

分享到:
评论

相关推荐

    flex 事件流原理

    Flex的精髓之一就是事件和绑定机制,了解之后,能帮助大家更灵活的设计程序,也对新手上路有一定的帮助。 讲解可能不太系统,也不全面,有很多没有深入。如果高手看到后有疑问,欢迎指正。当然各位也可以提出自己的...

    Flex企业应用开发实战源代码

    8.4 深入了解PrintJob 268 8.5 实战PrintJob—实现一个票据打印组件 270 8.5.1 组件结构 270 8.5.2 IReceiptPrinter和 DefaultReceiptPrinter 271 8.5.3 ReceiptTemplate 273 8.5.4 TemplateDescriptor 274 ...

    Spring技术内幕:深入解析Spring架构与设计原理

    一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的Java EE组件在Spring中的实现原理;第三部分讲述了ACEGI安全框架、DM模块以及Flex...

    Spring技术内幕:深入解析Spring架构与设计原理(第2版)

    第一部分详细分析了spring的核心:ioc容器和aop的实现,能帮助读者了解spring的运行机制;第二部分深入阐述了各种基于ioc容器和aop的java ee组件在spring中的实现原理;第三部分讲述了acegi安全框架、dm模块以及flex...

    Spring技术内幕:深入解析 Spring架构与设计原理.pdf

    第一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的Java EE组件在Spring中的实现原理;第三部分讲述了ACEGI安全框架、DM模块以及Flex...

    SPRING技术内幕:深入解析SPRING架构与设计原理

    第一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的Java EE组件在Spring中的实现原理;第三部分讲述了ACEGI安全框架、DM模块以及Flex...

    Spring技术内幕:深入解析Spring架构与设计原理(第2版)

    第一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的JavaEE组件在Spring和的实现原理,第三部分讲述了ACEGI安全框架、DM模块以及Flex...

    Spring技术内幕:深入解析Spring架构与设计原理(第2版) 决战大数据时代!IT技术人员不得不读! 计文柯 著

    一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的Java EE组件在Spring中的实现原理;第三部分讲述了ACEGI安全框架、DM模块以及Flex...

    Spring技术内幕:深入解析 Spring架构与设计原理

    第一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的Java EE组件在Spring中的实现原理;第三部分讲述了ACEGI安全框架、DM模块以及Flex...

    深入解析Spring架构与设计原理

    第一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的JavaEE组件在Spring中的实现原理;第三部分讲述了ACEGI安全框架、DM模块以及Flex...

    Spring 技术内幕

    第一部分详细分析了spring的核心:ioc容器和aop的实现,能帮助读者了解spring的运行机制;第二部分深入阐述了各种基于ioc容器和aop的java ee组件在spring中的实现原理;第三部分讲述了acegi安全框架、dm模块以及flex...

    C语言半自动词法分析器和半自动语法分析器.zip

    通过实现半自动词法分析和语法分析器,开发者可以深入理解编译器的工作原理,提高C编程技能,并为进一步学习编译原理和编程语言理论打下基础。此外,这个项目对于希望进入编译器设计、程序分析和代码生成等领域的人...

    asp.net知识库

    理解DataSet的数据缓存机制 存储过程 可按任意字段排序的分页存储过程(不用临时表的方法,不看全文会后悔) 常用sql存储过程集锦 存储过程中实现类似split功能(charindex) 通过查询系统表得到纵向的表结构 将数据库表...

Global site tag (gtag.js) - Google Analytics