1

Ниже приведен код, с которого я только начал работать (эксперимент генератора аватаров). Я хочу, чтобы иметь возможность щелкнуть по кнопке и изменить положение элемента canvas, но у меня возникают проблемы с некоторыми вещами.Доступ к глобальной переменной и асинхронной проблеме

В функции событий нажмите на кнопку I console.log из canvasTop ...

console.log(this.canvasTop); 

... однако, он получает не определено. Я могу получить доступ к переменной в другом месте кода, кроме внутри этой функции события click. Почему так?

Другое дело, следующие две строки ...

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)' решение должно быть относительно очевидным после этого. –

ответ

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', но да. –

+0

+1 Я бы рекомендовал посмотреть на шаблон плагина jQuery, чтобы увидеть традиционное использование 'base', но' self' в этом примере одно и то же и будет работать :) – Archer

+0

@KevinB вы абсолютно правы :) – robertklep

Смежные вопросы