监听器丢失对"this"的引用 - jQuery

Can*_*yer 0 javascript jquery

我有以下类初始化鼠标事件的canvas元素.监听器在构造函数中初始化,但是当我findxy在事件被触发时调用时,对变量的引用会this.flag导致错误,因为它们是未定义的,这使我相信监听器this在调用时会丢失其引用findxy.我不完全确定如何解决这个问题.提前致谢.

class Signature {
  constructor() {
    this.signed = false;
    this.prevX = 0;
    this.currX = 0;
    this.prevY = 0;
    this.currY = 0;
    this.dot_flag = false;
    this.flag = false;
    this.canvas = document.getElementById('can');

    this.ctx = this.canvas.getContext("2d");
    this.w = this.canvas.width;
    this.h = this.canvas.height;

    this.canvas.addEventListener("touchmove", function(e) {
      mobilexy('move', e)
    }, false);
    
    this.canvas.addEventListener("touchstart", function(e) {
      mobilexy('down', e)
    }, false);
    
    this.canvas.addEventListener("touchleave", function(e) {
      mobilexy('up', e)
    }, false);

    this.canvas.addEventListener("mousemove", function(e) {
      findxy('move', e)
    }, false);
    
    this.canvas.addEventListener("mousedown", function(e) {
      findxy('down', e)
    }, false);
    
    this.canvas.addEventListener("mouseup", function(e) {
      findxy('up', e)
    }, false);
    
    this.canvas.addEventListener("mouseout", function(e) {
      findxy('out', e)
    }, false);

    findxy(res, e) {
      if (res == 'down') {
        this.prevX = this.currX;
        this.prevY = this.currY;
        this.currX = e.pageX - this.canvas.offsetLeft;
        this.currY = e.pageY - this.canvas.offsetTop;

        this.flag = true;
        this.dot_flag = true;
        
        if (this.dot_flag) {
          this.ctx.beginPath();
          this.ctx.fillStyle = x;
          this.ctx.fillRect(currX, currY, 2, 2);
          this.ctx.closePath();
          this.dot_flag = false;
        }
      }
      
      if (res == 'up' || res == "out") {
        this.flag = false;
      }
      
      if (res == 'move') {
        if (this.flag) {
          this.prevX = this.currX;
          this.prevY = this.currY;
          this.currX = e.pageX - canvas.offsetLeft;
          this.currY = e.pageY - canvas.offsetTop;
          draw();
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

我的错误:

未捕获的ReferenceError:
在HTMLCanvasElement的findxy(jobs.self-09776d4c973306a740403ee614a19882dd0d4d402c0c72bba61747ef44c6ab2b.js?body = 1:191)
中未定义标志.(signature.self-e4f9a6f8d0069a7e6488dd64f3234fbdf4b0c2004f9de362da627d0176111f06.js体= 1:31)
findxy @ jobs.self-09776d4c973306a740403ee614a19882dd0d4d402c0c72bba61747ef44c6ab2b.js体= 1:191
(匿名)@ signature.self-e4f9a6f8d0069a7e6488dd64f3234fbdf4b0c2004f9de362da627d0176111f06.js体= 1:31 9时37分:56.162

Ror*_*san 5

范围不随电话转移.您需要将this引用作为参数传递:

this.canvas.addEventListener("mouseout", function (e) {
  findxy('out', e, this)
}, false); 

findxy(res, e, _this) {
  // call it something more appropriate than '_this' - this is just an example
  _this.prevY = ...;
}
Run Code Online (Sandbox Code Playgroud)

或者call()用来提供范围:

this.canvas.addEventListener("mouseout", function (e) {
  findxy.call(this, 'out', e)
}, false); 
Run Code Online (Sandbox Code Playgroud)

或者使用jQuery的替代方法call(),即$.proxy():

this.canvas.addEventListener("mouseout", function (e) {
  $.proxy(findxy, this, 'out', e)();
}, false); 
Run Code Online (Sandbox Code Playgroud)