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函數提供了callapplly方法,能夠重新設定函數調用的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

 

相關文章

Fixjs專欄

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章