【问题标题】:Javascript event listenerJavascript 事件监听器
【发布时间】:2017-02-15 23:44:58
【问题描述】:

我正在尝试用 Javascript 制作一个简单的 Pong 游戏。我有一个 Pong 类,我想创建一个方法来根据鼠标的移动方式移动播放器矩形:

class Player 
{
  constructor()
  {
   // do stuff
  }
}

class Pong
{
  constructor(canvas)
  {
   //do stuff
   this.player1 = new Player(true); // Create an instance of another class

  }

  handleMouseMove(event)
  {
    var y = event.clientY;

    // this.player1 is undefined!!
    console.log("this.player1: "+this.player1);
    this.player1.pos.y = y;
  }


function main()
{
  // Initialize canvas and context
  canvas = document.getElementById('mycanvas');

  const pong = new Pong(canvas);
  canvas.addEventListener('mousemove', pong.handleMouseMove);
}

每当我开始移动鼠标时,它都会告诉我 player1 未定义。如何将类方法设置为事件监听器并让它知道类的成员?

【问题讨论】:

  • 你的Player班级在哪里?
  • Player 类在 Pong 类之外,但在同一个文件中。我将编辑我的问题以表明这一点。

标签: javascript addeventlistener


【解决方案1】:

这是因为事件监听器内部的this 引用了触发事件的元素(画布)。您可以像这样使用bind 绑定this 关键字:

canvas.addEventListener('mousemove', pong.handleMouseMove.bind(pong));
//                                                       ^^^^^^^^^^^

bind 将返回一个函数,其 this 关键字设置为您提供的任何参数。

【讨论】:

  • 不是this,是pong
  • @ChemicalRocketeer 是的,我刚刚注意到了!我以为main 在课堂上Pong
【解决方案2】:

在我看来,这是 javascript 最糟糕的部分之一。当您将pong.handleMouseMove 传递给addEventListener 时,您正在传递函数本身。在这种情况下,当事件触发时,它会在 Pong 实例的上下文之外调用函数。您需要在handleMouseMove 上致电bind,如下所示:

canvas.addEventListener('mousemove', pong.handleMouseMove.bind(pong));

bind存在于所有函数中,并返回一个可以传递的新函数,并确保函数内部的this绑定到指定的参数(本例中为pong)。

编辑:ibrahim mahrir 的另一个答案是错误的,您必须将您的 pong 实例传递给 bind 函数。无论您传递什么,this 都会在您正在绑定的函数中分配给它。

【讨论】:

  • 你也可以canvas.addEventListener('mousemove', function(e) { pong.handleMouseMove(e); }) - 不是很好,但很常见
  • 我明白了...感谢您的解释。我接受了另一个答案,因为它更接近顶部(并且在我看到它时已修复)。谢谢!!
猜你喜欢
  • 2020-06-21
  • 1970-01-01
  • 2016-08-26
  • 2012-09-13
  • 2013-07-21
  • 2011-05-23
  • 2011-01-16
  • 1970-01-01
相关资源
最近更新 更多