Flash as3事件学习

来源:互联网 发布:癌症诊断书生成软件 编辑:程序博客网 时间:2024/05/18 17:42

事件是什么?

Event是一种反应机制,比如一个对象做了一件事(执行了某个函数),另一个对象就会对应的执行某个动作(某个函数)。
怎样才能达到上述效果呢?我们需要一个媒介来发送消息。


为什么需要事件?

1.一般我们先要达到通知消息的功能,都是用对象的外部接口,也就是传参数来通知,这种方式的一个弊端是:一旦对象的内部有变化,接口有改变,那么
就不得不修改所有的接口和执行函数。这与面向对象的思想不符,所以我们需要一个低耦合的机制(各对象之间的联系尽量少,方便修改)来完成消息的传递。
2.异步处理,作为线程的一个补充。Flash as3里没有多线程的概念,一旦我们想要达到多线程的效果,就必须要使用事件。


Flash as3里的事件是什么?

是基于document object model 3,简称dom3来处理的机制。dom3是业界公认的一套处理事件的方式。
dom3处理事件的流程如下:
     1.注册侦听器,即声明某对象一旦执行了函数a要执行函数b。
     2.发送事件,即执行函数a。
     3.帧听事件,执行函数b。
     4.移除事件,移除声明。
对应到具体的代码例子,比如我们模拟鼠标点击,发送鼠标事件。
/*     模拟鼠标的点击事件,让其自动点击两次。*/package{     import flash.events.MouseEvent;     import flash.display.Sprite;     public class SimulateMouse extends Sprite{     public function SimulateMouse(){          var clickEvt:MouseEvent = new MouseEvent(MouseEvent.CLICK, true, false, 0, 0, null, false, false, false, false, 0);//这里我生成一个鼠标点击事件对象,具体的鼠标事件后面会讲到          this.stage.addEventListener(MouseEvent.CLICK, f);//给舞台注册一个鼠标点击的侦听器          this.stage.dispatchEvent(clickEvt);//发送鼠标点击的事件          this.stage.dispatchEvent(clickEvt);          this.stage.removeEventListener(MouseEvent.CLICK, f);//移除鼠标点击事件监听     }         function f(e:MouseEvent):void{          trace("this is a click!");     }     }}


Flash as3中如何自定义事件?

有了个初步的印象之后,我们一步一步来自定义事件。
     我们要了解事件的几个因素,如果按流程来分,你首先需要一个能够发送事件的对象,在as3中,只要继承了EventDispatcher类的对象都可以发送事件,所有的显示对象都继承自DisplayObject,而DisplayObject又继承自EventDispatcher,所以我们的显示对象都可以发送事件,显示对象有一个事件流机制,这个后面再讲。所以我们自定义的对象只要继承EventDispatcher就可以发送事件了。
     然后我们要有一个事件类,如果一个事件不需要传递额外的信息,我们直接用系统的事件发送就好了。
var evt:Event = new Event("新事件名称");obj.dispatcher(evt);
如果要在事件中加入属性传递信息,一般需要重写clone(),toString()方法。自定义事件要继承Event.
     然后我们要有一个事件的接受者,可以是对象的成员方法,也可以是一个函数。

了解了自定义事件的流程之后,我们不急着自己写事件,先看一下系统给我们提供的事件类,这样你对事件会有一个更清楚的认识。

Event类

    Event类在flash.events包中,直接继承自Object,虽然不是顶级类,但是其作用一点都不输给顶级类。
    公开的实例属性有:type,target,currentTarget,eventPhase,bubbles,cancelable.
    type是事件的名字,字符串类型,用来区分事件。
    target是Object类型,持有引用,指向最初发出事件的那个对象。
    currentTarget,eventPhase,bubbles这三个属性和事件流机制有关,后面会讲到。
     cancalable表示这个事件引起的默认动作是否可以被取消,一般和preventDefault()方法结合在一块儿使用的,比如我鼠标点了一个东西,还没有抬起,移动了鼠标位置,就取消了这个点击事件的动作。
     注意这些属性都不是实例属性,是由getter()方法实现的,是只读属性,没有setter()方法,除了type,bubbles,cancelable可以在构造函数中赋初值,其余属性都是在事件发生过程中系统自己指定的。我们自定义事件的时候可以用这种方法设置属性。
     还有其他属性和方法大家可以在adobe的官方文档上查阅,点击打开链接
     除了属性和方法,Event类还定义了26个静态字符常量,即26个事件类型,涵盖了系统常用的时间,比如COPY(发生复制时事件),ADDED(对象被添加到显示列表的事件)等,利用这些事件我们可以实现很多有意思的功能。
   Event类的构造函数
          public function Event(type:String, bubbles:Boolean = false, cancelable:Boolean = false)
   我们自定义事件的时候继承Event,要通过super("事件类型")的方法把事件类型传给父类的构造函数,作为默认的事件类型。
   Event类的方法
      clone()在重复发送事件的时候会自动调用clone方法,返回事件的拷贝,因此在自定义事件的时候,要重写clone方法,增加自己的属性拷贝。
      toString()返回表示对象用字符表示的形式,自定义事件要重写,增加自己的属性。
      isDefaultPrevented()和preventDefault()用来阻止事件的默认行为发生。
      stopImmediatePropagation()、stopPropagation()用来阻止事件的传播,和事件流有关。

侦听器

     addEventListener是EventDispatcher类的方法, EventDispatcher类在flash.events包中,继承自Object,实现了IEventDispatcher接口,后面我们也可以自己实现这个接口来发送事件。
     下面我们来看EventDispatcher类的方法:

addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
type是事件类型,
listener是函数对象,
useCapture是有关事件流的捕获,
priority是事件发生的优先级,
useWeakReference是事件的弱引用,设置为true的时候,当我们移出了对象,而没有移出对象那个的监听,系统会自动回收这个监听,如果社会为false,则不会回收,不过垃圾回收是有一定时间延迟的,一般我们都会在删除对象前,移除掉它身上的监听。    

dispatchEvent(event:Event):Boolean
这个方法就是发送事件的方法。

hasEventListener(type:String):Boolean

willTrigger(type:String):Boolean
这两个方法都是检测对象有没有注册某事件类型的,不同的是willTrigger方法还会检测显示列表对象父级所有的侦听器。

removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
移除帧听的方法。


自定义发送事件的三种方式

1.继承EventDispatcher类
     一般的自定义方式。
2.复合EventDispatcher对象
     当我们不仅仅把事件的发送类看做发送事件的类,而是其他类的时候,我们用复合。
3.实现IEventDispatcher接口
     当我们因为继承了其他类不能够继承EventDispatcher类的时候,我们实现接口。
具体的方法可以参考《ActionScript3.0殿堂之路》这本书,作者有详细的例子说明。

下面我们来自定义一个小明见到老王问好的事件。

自定义事件举例

TestEvent.as
package myEvent{     import flash.display.Sprite;     public class TestEvent extends Sprite{          public function TestEvent(){               var xiaoming:XiaoMing = new XiaoMing();               var laowang:LaoWang = new LaoWang();               xiaoming.addEventListener(SayEvent.SAY_HELLO, laowang.replyEvent);//注册事件               xiaoming.addEventListener(SayEvent.SAY_GOODBYE, laowang.replyEvent);               xiaoming.meetPeople();//发出事件               xiaoming.leavePeople();               xiaoming.removeEventListener(SayEvent.SAY_HELLO, laowang.replyEvent);//移除事件               xiaoming.removeEventListener(SayEvent.SAY_GOODBYE, laowang.replyEvent);                              /*var evt1:SayEvent = new SayEvent("say_goodbye");               evt1.books = ["1", "2", "3"];               var evt2 = evt1;//和clone()的对比               evt1 = null;               trace(evt1);               trace(evt2);               xiaoming.dispatchEvent(evt2);*//*输出:[object XiaoMing] say: Hello!c++从入门到放弃,php是最好的语言,我的编程笔记[object XiaoMing] say: goodbye!c++从入门到放弃1,php是最好的语言1,我的编程笔记1*/          }     }}

XiaoMing.as
package myEvent{     import flash.events.EventDispatcher;     public class XiaoMing extends EventDispatcher{          private var sname:String;          public function XiaoMing(sname:String="xiaoming"){               this.sname = sname;          }          public function meetPeople():void{               var sayHello:SayEvent = new SayEvent("say_hello");               sayHello.books = ["c++从入门到放弃", "php是最好的语言", "我的编程笔记"];               dispatchEvent(sayHello);//发送sayHello事件          }          public function leavePeople():void{               var sayHello:SayEvent = new SayEvent("say_goodbye");               sayHello.books = ["c++从入门到放弃1", "php是最好的语言1", "我的编程笔记1"];               dispatchEvent(sayHello);          }     }}

LaoWang.as
package myEvent{     public class LaoWang{          public function replyEvent(evt:SayEvent):void{               if (evt.type == "say_hello"){                    trace(evt.target+" say: Hello!");               }else{                    trace(evt.target+" say: goodbye!");               }               trace(evt.books);          }     }}

SayEvent.as
package myEvent{     import flash.events.Event;     public class SayEvent extends Event{          public static const SAY_HELLO:String = "say_hello";          public static const SAY_GOODBYE:String = "say_goodbye";//定义两个事件类型          private  var _books:Array;//新增的事件属性          public function SayEvent(eventType:String="say_hello"){               super(eventType);          }//用setter和getter方法设置_books属性          public function set books(bookArr:Array):void{               _books = bookArr;          }          public function get books():Array{               return _books;          }          override public function toString():String{               return formatToString("SayEvent", "type", "bubbles", "cancelable", "eventPhase", "books");          }          //重写clone方法,注意这里的由于新增了事件类型,可能会有问题。          override public function clone():Event{               var tmpEvt:SayEvent = new SayEvent();               tmpEvt._books = _books;               return tmpEvt;          }     }}



2 0