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。
相關文章