正确区分自定义事件和自定义事件类 ,如果你只是简单地发送一个你自己的事件而不需要更多信息,可以使用
dispatchEvent(myInfo)
来实现, 我们看到自定义事件很简单,只需给Event类传入一个特殊的不与内置事件类型重复的字符串即可 。
可以做如下测试:
![自定义事件和自定义事件类 - Davis - GotoAndPlay部落 自定义事件和自定义事件类 - Davis - GotoAndPlay部落](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
var outer = new Sprite();
outer.name = " Outer " ;
outer.graphics.beginFill( 0xFF0000 );
outer.graphics.drawRect( 0 , 0 , 100 , 100 );
// mid
var mid = new Sprite();
mid.name = " mid "
mid.graphics.beginFill( 0x00FF00 );
mid.graphics.drawRect( 0 , 0 , 50 , 50 );
// inner
var inner = new Sprite();
inner.name = " inner " ;
inner.graphics.beginFill( 0x0000FF );
inner.graphics.drawRect( 0 , 0 , 25 , 25 );
// addChild
outer.addChild(mid);
mid.addChild(inner);
addChild(outer);
outer.x = outer.y = 100 ;
// 添加侦听器
outer.addEventListener( " myOwnEvent " ,myOwnEventHandler, true ); // 注意此处将useCapture设为true所以会在捕获阶段调用侦听器
mid.addEventListener( " myOwnEvent " ,myOwnEventHandler, true ); // 同上
inner.addEventListener( " myOwnEvent " ,myOwnEventHandler);
function myOwnEventHandler(evt){
trace( " 事件流当前阶段: " + evt.eventPhase)
trace( " 鼠标点击处最内层的显示对象(target)是: " + evt.target.name)
trace( " 事件当前流经显示对象(currentTarget)是: " + evt.currentTarget.name)
trace( " =============================================================== " )
}
var myInfo = new Event( " myOwnEvent " )
inner.dispatchEvent(myInfo) // 由inner向FlashPlayer提出请求把一个myOwnEvent的事件对象加入事件流
输出 :
事件流当前阶段:1
鼠标点击处最内层的显示对象(target)是:inner
事件当前流经显示对象(currentTarget)是:Outer
===============================================================
事件流当前阶段:1
鼠标点击处最内层的显示对象(target)是:inner
事件当前流经显示对象(currentTarget)是:mid
===============================================================
事件流当前阶段:2
鼠标点击处最内层的显示对象(target)是:inner
事件当前流经显示对象(currentTarget)是:inner
===============================================================
可以看到我们自定义的事件被加入到了事件流中并且被outer,mid,inner收到了
这里要补充一点, dispatchEvnet的调用对象将会被作为事件的目标对象(target)
晕了没?
你可以修改一下上面的代码来帮助你理解
代码:
trace(myInfo.target) // 输出调用dispatchEvent方法前的target的名字,输出结果是null
inner.dispatchEvent(myInfo)
trace(myInfo.target.name) // 输出调用dispatchEvent方法前的target的名字,输出结果是inner
如果你认真看完了上面的文字,你应该对自定义事件有了一定了解,在一般情况下,这种方法已经够用了,如果你还需要更复杂的事件的话,你就可以考虑创建你自己的 事件类 了
编写自己的事件类
在上面的Mp3播放器例子中我们提到了给Mp3播放控制部分发送一个ProgressChangeEvent事件,现在继续
给它发送这个事件的目标是要让它知道播放进度改变了,还要让它知道进度变成了多少,这就是参数progressBar.progress的作用
自定义事件类
![自定义事件和自定义事件类 - Davis - GotoAndPlay部落 自定义事件和自定义事件类 - Davis - GotoAndPlay部落](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
{
import flash.events.Event;
public class ProgressChangeEvent extends Event
{
static private const PROGRESS_CHANGE = " progresschange " ; // 是不是跟MouseEvent.MOUSE_DOWN长得很像,其实MouseEvent差不多也是这么写出来的
public var position:Number = 0 ; // 这是我们新加的变量,用来存储进度信息。
public function ProgressChangeEvent(pos:Numbre)
{
super (PROGRESS_CHANGE); // 调用父类的构造函数,将PROGRESS_CHANGE设置为默认事件类型
position = pos;
}
public override function clone():Event // 你应负责任地重写clone方法
{
var cloneEvent = new ProgressEvent();
cloneEvent.position = this .position;
return cloneEvent;
}
public override function toString():String // 你应负责任地重写toStrin方法
{
return formatToString( " ProgressChangeEvent " , " type " , " bubbles " , " cancelable " , " eventPhase " , " position " );
}
}
}
一个修秀的程序员应该在自定义类中重写clone和toString方法,不论你是否会用到这两个方法!! 因为在调用dispatchEvent(myInfo)时实际是把myInfo对象的一个拷贝给了dispatchEvent方法。
-_-!!终于写完了,现在我们可以使用自己写的事件类了。
把上面的代码保存成ProgressChangeEvent.as文件,然后在同一目录下新建一个fla文件F9打开动作面板输入:
代码:
![自定义事件和自定义事件类 - Davis - GotoAndPlay部落 自定义事件和自定义事件类 - Davis - GotoAndPlay部落](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
// PlayerContralCenter
var PlayerContralCenter = new Sprite();
PlayerContralCenter.name = " PlayerContralCenter "
PlayerContralCenter.graphics.beginFill( 0x00FF00 );
PlayerContralCenter.graphics.drawRect( 0 , 0 , 100 , 100 );
// progressBar
var progressBar = new Sprite();
progressBar.name = " progressBar "
progressBar.graphics.beginFill( 0xFF0000 );
progressBar.graphics.drawRect( 0 , 0 , 100 , 5 );
// addChild
PlayerContralCenter.addChild(progressBar);
addChild(PlayerContralCenter);
progressBar.y = 50
PlayerContralCenter.x = PlayerContralCenter.y = 100
// PlayerContralCenter侦听ProgressChangeEvent事件,将useCapture设置为true的原因是我们的自定义事件类是不冒泡的(你也可以修改成可冒泡的),所以必须在捕获阶段响应
PlayerContralCenter.addEventListener(ProgressChangeEvent.PROGRESS_CHANGE,handler, true );
progressBar.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
function handler(evt:ProgressChangeEvent){
trace( " 我是 " + evt.currentTarget.name + " ,我收到了 " + evt.type + " 事件, " + " 事件信息是 " + evt.position);
}
function mouseDownHandler(evt:MouseEvent){
var pos = evt.target.mouseX / evt.target.width;
progressBar.dispatchEvent( new ProgressChangeEvent(pos));
}
输出 : 我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.42
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.84
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.94
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.97
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.05