Fixjs——事件回调的this
Fixjs介绍
Fixjs是一款javascript界面基础框架,主要为开发复杂组件提供底层的框架支持。
框架的类与接口我会尽量参考flash框架的实现。同时,我也会开放Fixjs的源代码,欢迎同仁一起学习、交流。
事件回调的this问题
在javascript中,函数调用的时候,this指向调用的对象,这个特性会造成代码上下文的不一致。请看一下代码片段:
在hui.layout.MovableExtension实例中向this._target注册一个mousedown事件,回调时调用hui.layout.MovableExtension实例的mouseDownHandler处理函数
hui.layout.MovableExtension = fixjs.Object.extend({
init: function(target) {
this._target = target;
//略…
this.stagePoint = new fixjs.geom.Point(0, 0);
//略…
this._target.addEventListener(fixjs.events.MouseEvent.MOUSE_DOWN, this._mouseDownHandler);
},
_mouseDownHandler:function (event) {
if (event.currentTarget!= this._target || event.type != fixjs.events.MouseEvent.MOUSE_DOWN)
return;
//以下代码将报错,因为this并不指向当前的hui.layout.MovableExtension实例
this.stagePoint.x = event.stageX;
this.stagePoint.y = event.stageY;
//略…
现在的问题是,mouseDownHandler中的this并不指向当前hui.layout.MovableExtension实例,这导致事件注册和事件处理的上下文不一致,对代码的编写造成困扰。
修正事件回调的this
Javascript函数提供了call或applly方法,能够重新设定函数调用的this。如果在注册事件的时候,传入回调时的this对象,在派发事件时调用call设置this对象,上下文不一致的问题就解决了。
因此,fixjs.events.EventDispatcher的注册和事件派发要做一些调整:
注册事件时addEventListener新增caller参数,由外部传入函数回调的this对象;派发事件时调用函数的calll方法并传入caller。
fixjs.events.EventDispatcher = fixjs.Object.extend({
//略…
addEventListener: function(type, func, caller){
if (!this._isFunction(func)){
return;
}
var list = this._events.get(type);
if (!list) {
list = [];
this._events.set(type, list);
}
var item = { func: func,caller: caller };
if (!item.caller)
item.caller = this; //caller为空时将指向当前的fixjs.events.EventDispatcher实例
list.push(item);
},
dispatchEvent: function(event) {
if (!(event instanceof fixjs.events.Event))
return;
var list = this._events.get(event.type);
if (!list || !list.length) {
return;
}
if (!event.target){
event.target = this;
if (this._target)
event.target = this._target;
}
event.currentTarget = this;
if (this._target)
event.currentTarget = this._target;
var buffer = list.slice(0);
while (buffer.length){
varitem = buffer.splice(0, 1)[0];
if (list.indexOf(item) >= 0) {
item.func.call(item.caller,event); //调用函数的call并传入caller
}
}
}
});
经过上述调整后,事件回调的上下文能够自行控制了,以下是修正后的hui.layout.MovableExtension代码:
hui.layout.MovableExtension = fixjs.Object.extend({
init: function(target) {
this._target = target;
//略…
this.stagePoint = new fixjs.geom.Point(0, 0);
//略…
this._target.addEventListener(fixjs.events.MouseEvent.MOUSE_DOWN,this._mouseDownHandler,this); //传入当前的hui.layout.MovableExtension实例this
},
_mouseDownHandler:function (event) {
if (event.currentTarget!= this._target || event.type != fixjs.events.MouseEvent.MOUSE_DOWN)
return;
// this指向当前的hui.layout.MovableExtension实例
this.stagePoint.x = event.stageX;
this.stagePoint.y = event.stageY;
//略…
注册事件时传入多一个参数this。
相关文章