2015-01-01 3 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. методов, «это» не определено, как будто оно каким-то образом потеряло область видимости?

Мне понравилось бы решение и объяснение. Благодаря!

+1

Значение 'this' определяется ** только ** тем, как вызывается функция. Вместо передачи 'obj.drawMove' непосредственно в функции регистрации обработчика событий передайте анонимную функцию-обертку, которая вызывает' drawMove' через ссылку на объект. – Pointy

ответ

2

Вы можете связать «это» для обратного вызова события, как так:

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

Когда обратный вызов инициируется по событию, он должен иметь правильное «это».

2

Значение «this» зависит от способа вызова функции.

В первом случае, вы вызываете функцию drawBegin непосредственно из вашего класса DrawLayer:

this.drawBegin("INIT TEST"); 

в этом случае эта переменная представляет DrawLayer OBJ.

При вызове функции через событие

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"); 
}