2015-01-01 62 views
1

考慮下面的代碼...使用Hammer.js但我認爲這可能是一個通用的Javascript問題:訪問「這個」從事件原型

var drawLayer = new DrawLayer(document.getElementById('canvasContainer')); 

function DrawLayer(targetElement) { 
    this.foo = "bar"; 

    this.gestureDetection = new Hammer.Manager(targetElement); 
    this.gestureDetection.add(new Hammer.Pan({ 
      direction : Hammer.DIRECTION_ALL, 
      threshold : 0 
     })); 
    this.gestureDetection.add(new Hammer.Press({ 
      time : 0, 
      threshold : 5 
     })); 
    this.gestureDetection.on("press", this.drawBegin); 
    this.gestureDetection.on("panmove", this.drawMove); 
    this.gestureDetection.on("panend pressup", this.drawEnd); 

    this.drawBegin("INIT TEST"); 
} 

DrawLayer.prototype.drawBegin = function (gestureData) { 
    console.log(typeof(this.foo)); 
    console.log("DRAW BEGIN!"); 
} 

DrawLayer.prototype.drawMove = function (gestureData) { 
    console.log(this.foo); 
    console.log("DRAW MOVE!"); 
} 

DrawLayer.prototype.drawEnd = function (gestureData) { 
    console.log(this.foo); 
    console.log("DRAW END!"); 
} 

當我在第一次運行它,我得到這個,符合市場預期:

string 
DRAW BEGIN! 

但是當實際處理的手勢(即當圖紙的東西是通過事件的稱呼),我得到:

undefined 
DRAW BEGIN! 

更重要的是,似乎在處理任何這些drawBegin/etc時。方法,「this」是未定義的,好像它以某種方式失去了範圍?

我會喜歡解決方案和解釋。謝謝!

+1

'this'的值僅由調用函數的方式**確定。不是直接將'obj.drawMove'傳遞給事件處理程序註冊函數,而是傳遞一個匿名包裝函數,該函數通過對象引用調用'drawMove'。 – Pointy

回答

2

可以綁定「這個」將事件回調,像這樣:

this.gestureDetection.on("press", this.drawBegin.bind(this)); 

當回調被觸發通過這件事,它應該有正確的「這個」。

2

「this」的值取決於函數調用的方式。

在第一種情況下,你直接從你的DrawLayer類調用drawBegin功能:

this.drawBegin("INIT TEST"); 
在這種情況下

,這個變量代表的obj DrawLayer。

當你通過一個事件

this.gestureDetection.on("press", this.drawBegin); 

調用一個函數「這個」變量可以通過「上」來表示任何東西(誰觸發事件通常是事件本身或對象)的函數來包裝。

試圖改變你的代碼如下,看看它的工作原理:

function DrawLayer(targetElement) { 
    this.foo = "bar"; 

    this.gestureDetection = new Hammer.Manager(targetElement); 
    this.gestureDetection.add(new Hammer.Pan({ 
      direction : Hammer.DIRECTION_ALL, 
      threshold : 0 
    })); 
    this.gestureDetection.add(new Hammer.Press({ 
      time : 0, 
      threshold : 5 
    })); 
    this.gestureDetection.on("press", this.drawBeginWrapper); 
    this.gestureDetection.on("panmove", this.drawMove); 
    this.gestureDetection.on("panend pressup", this.drawEnd); 

    var _self = this; 

    this.drawBeginWrapper = function(gestureData) { 
      _self.drawBegin(gestureData); 
    } 

    this.drawBegin("INIT TEST"); 
}