EventDispatcher代码分析 |
| 作者:佚名 来源:闪吧 作者: AOL 更新:2007-1-13 20:48:31 错误报告 我要投稿 |
类的路径: classes/mx/events/EventDispatcher.as 这个类所有的属性和方法都是静态的。这说明,我们不必要实例化一个EventDispatcher,实例化也没有意义。 这个类有一个属性:_fEventDispatcher。它是这个类在内部的实例,作用是可以向别的对象添加方法。 我们在外部用到的这个类的方法有这么几个: initialize(object:Object):Void dispatchEvent(eventObj:Object):Void addEventListener(event:String, handler):Void removeEventListener(event:String, handler):Void 这是flash MX的ASBroadcaster有点儿相似, 事实上实现方法也有点儿相似。只是ASBroadcaster还有一些bug。在flashcoder wiki里面有相关的资料。
Dispatcher的例子: import mx.events.EventDispatcher; King = {}; // 产生国王 EventDispatcher.initialize(King); // 初始化国王为驱使者 subject = {}; // 产生奴仆 King.addEventListener("onKingScream",subject); //把它加到国王的被驱使者 //告诉我们的奴仆,他应该做的事 subject.onKingScream = function() { trace("带葡萄过来!"); } // 这里我们让国王高吼两次, 用来加强语气,:) King.dispatchEvent({type:"onKingScream"}); King.dispatchEvent({type:"onKingScream"}); 函数一: static function initialize(object:Object):Void { if (_fEventDispatcher == undefined) { _fEventDispatcher = new EventDispatcher; } object.addEventListener = _fEventDispatcher.addEventListener; object.removeEventListener = _fEventDispatcher.removeEventListener; object.dispatchEvent = _fEventDispatcher.dispatchEvent; object.dispatchQueue = _fEventDispatcher.dispatchQueue; } 用类的静态属性_fEventDispatcher的方法来传递给object。这就是刚才提到的这个属性的作用。这样的话, 我们可以使用object.addEventListener()、object.removeEventListener()、object.dispatchEvent()这三个方法。上面的例子中就用到了其中的两个方法。
函数二: function addEventListener(event:String, handler):Void { var queueName:String = "__q_" + event; if (this[queueName] == undefined) { this[queueName] = new Array(); } _global.ASSetPropFlags(this, queueName,1);
EventDispatcher._removeEventListener(this[queueName], event, handler); this[queueName].push(handler); } 这就表明每一种事件都存在一个数组EventDispatcher[“__q_onKingScream”]中, 而数组的里面存储的数据则是事件侦听器的引用。 像国王的那个例子,假如是 for(var i:Number=0;i<5;i++) { King.addEventListener(“onKingScream”,listenObj[i]); } 假设这段代码前,listenObj[i]就已经定义了。那么就成了一个这样的数组: EventDispatcher[“__q_onKingScream”]
函数三: function removeEventListener(event:String, handler):Void { var queueName:String = "__q_" + event; EventDispatcher._removeEventListener(this[queueName], event, handler); } 调用内部函数_removeEventListener(),传递参数第一个就是刚才提到的那个数组。 函数四: static function _removeEventListener(queue:Object, event:String, handler):Void { if (queue != undefined) { var l:Number = queue.length; var i:Number; for (i = 0; i < l; i++) { var o = queue[i]; if (o == handler) { queue.splice(i, 1); return; } } } } 这是一个比较重要的函数,它实现删除一个事件的侦听器,其实是删除引用。假如数组里面有一个侦听器的引用跟handler相同,那么就从数组中删除。 函数五: function dispatchEvent(eventObj:Object):Void { if (eventObj.target == undefined) eventObj.target = this; this[eventObj.type + "Handler"](eventObj); (a) // Dispatch to objects that are registered as listeners for // this object. this.dispatchQueue(this, eventObj); } 这个函数就是我们派发事件的函数了。假如你用了类似enventNameHandler的方法,比如说clickHandler,(a)就会帮你实现这个方法。后面就调用了dispatchQueue()函数, 这才是我们dispatch事件实现的真正函数, 是一个内部的函数。我们这里传了this参数过去,也就是EventDispatcher的引用。
函数五:
function dispatchQueue(queueObj:Object, eventObj:Object):Void { var queueName:String = "__q_" + eventObj.type; var queue:Array = queueObj[queueName]; if (queue != undefined) { var i:String; // loop it as an object so it resists people removing listeners during dispatching for (i in queue) { var o = queue[i]; var oType:String = typeof(o); // a handler can be a function, object, or movieclip if (oType == "object" || oType == "movieclip") { // this is a backdoor implementation that // is not compliant with the standard if (o.handleEvent == undefined) { o[eventObj.type](eventObj); (b) } else // this is the DOM3 way { o.handleEvent(eventObj); (c) } } else // it is a function { o.apply(queueObj, [eventObj]); (d) } } } } 派发事件了,(b)就是指handleEvent方法。国王的那个例子就是这用这个函数实现的。 (c)就是DOM3的标准方式 myObj.handleEvent = function(o){ if (o.type == "click"){ // your code here } else if (o.type == "enter"){ // your code here } } 不是很方便。 (d)指传递了函数o,这样的话o.appy()就可以实现这个函数的调用。 doc文件压缩包,有图!
点击浏览该文件 突然发现有一个地方有错误,昨晚因为太赶,所以没注意。 this不是指EventDispatecher类的引用,而是initialize()函数定义的那个派发对象object的引用。
|
|
| 文章录入:skyuu 责任编辑:skyuu |
|
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |