2013-05-01 74 views
1

下面是我剛開始工作的一些代碼(化身發生器實驗)。我希望能夠點擊按鈕並更改畫布元素的位置,但我遇到了一些麻煩。訪問全局變量和異步問題

在按鈕上我CONSOLE.LOG出canvasTop click事件函數...

console.log(this.canvasTop); 

...然而,它就會不確定。除了這個點擊事件函數外,我可以在代碼中的任何地方訪問變量。這是爲什麼?

另一件事是接下來的兩行...

this.canvasTop += 10; 
AvatarGenerator.canvas(); 

...第一個在這些線路上我想迭代canvasTop值,並在第二行調用函數繪製帆布。但是,似乎第二行在第一行之前運行(是的,我知道JS是異步的),這意味着直到下次單擊按鈕時,canvas元素纔會移動。我該如何解決這個問題?

在此先感謝!

代碼:

AvatarGenerator = { 

    canvasTop: 50, 
    canvasLeft: 50, 
    canvas: $('#canvas')[0], 
    context: canvas.getContext('2d'), 

    init: function() { 
     AvatarGenerator.canvas(); 
     AvatarGenerator.toolBox(); 
    }, 

    canvas: function() { 
     console.log(this.canvasTop); // <-- 50 
     this.context.beginPath(); 
     this.context.moveTo(this.canvasLeft, this.canvasTop); 
     this.context.lineTo(300, 300); 
     this.context.stroke(); 
    }, 

    toolBox: function() { 
     var moveLeftBtn = $('#moveLeftBtn'); 

     moveLeftBtn.on('click', function(){ 
      console.log(this.canvasTop); // <-- undefined, why? 

      this.canvasTop += 10; 
      AvatarGenerator.canvas(); 
     }); 
    } 
}; 
+3

'this'是不是你認爲是。 'console.log(this)'解決方案應該比較明顯。 – 2013-05-01 15:24:21

回答

4

的點擊處理程序被調用在不同的環境,所以this不指向你的對象了。

試試這個:

var self = this; 
moveLeftBtn.on('click', function(){ 
    console.log(self.canvasTop); 

    self.canvasTop += 10; 
    AvatarGenerator.canvas(); 
}); 

或者,現代瀏覽器,您可以將對象綁定到你的函數,所以你不需要self

moveLeftBtn.on('click', function(){ 
    console.log(this.canvasTop); 

    this.canvasTop += 10; 
    AvatarGenerator.canvas(); 
}.bind(this)); 
//^^^^^^^^^^ this determines what 'this' in the callback function is pointing to 
+2

在這種情況下,你也可以使用'AvatarGenerator'而不是'this'或'self',但是。 – 2013-05-01 15:27:37

+0

+1我建議看看一個jQuery插件模板,看看'base'的傳統用法,但'self'在這個例子中是一樣的東西,並會工作:) – Archer 2013-05-01 15:28:13

+0

@KevinB你絕對正確:) – robertklep 2013-05-01 15:28:14