2016-09-28 81 views
-2

我正在将教程游戏转换为更强大的应用程序模式,并遇到了重构我的事件侦听器的问题。addEventListener无法正常工作

在原来的代码,我有听众设置在主函数中定义的回调:

(function() { 
    "use strict"; 
    GAME.init(); 
    function main() { 
     GAME.stopMain = window.requestAnimationFrame(main); 

     GAME.draw(); 

     GAME.update(); 
    } 

    document.addEventListener("keydown", keyDownHandler, false); 
    document.addEventListener("keyup", keyUpHandler, false); 

    function keyDownHandler(e) { 
     if (e.keyCode === 39) { 
      GAME.inputs.rightPressed = true; 
     } else if (e.keyCode === 37) { 
      GAME.inputs.leftPressed = true; 
     } 
    } 

    function keyUpHandler(e) { 
     if (e.keyCode === 39) { 
      GAME.inputs.rightPressed = false; 
     } else if (e.keyCode === 37) { 
      GAME.inputs.leftPressed = false; 
     } 
    } 

    main(); 
})(); 

当我换我的听众和回调出去调用GAME.inputs.init();和创造的GAME.inputs此方法:

GAME.inputs: { 
    keyDownHandler: function(e) { 
     if (e.keyCode === 39) { 
      this.rightPressed = true; 
     } else if (e.keyCode === 37) { 
      this.leftPressed = true; 
     } 
    }, 

    keyUpHandler: function(e) { 
     if (e.keyCode === 39) { 
      this.rightPressed = false; 
     } else if (e.keyCode === 37) { 
      this.leftPressed = false; 
     } 
    }, 

    init: function() { 
     document.addEventListener("keydown", this.keyDownHandler, false); 
     document.addEventListener("keyup", this.keyUpHandler, false); 
    } 
}; 

事件侦听器停止注册。我之前有过这个问题,只是回到了旧的方式,但我想知道为什么这不起作用。

+0

我能想到的几个可能的原因,但你却没有提供[MCVE]所以我不能告诉他们是对的。 (在你的测试用例中,你永远不会调用'init',你的事件处理函数不会做任何事情)。 – Quentin

+1

您是否检查过被调用的处理程序?那个'init'已经被调用了? – tcooc

+0

[似乎工作](https://jsfiddle.net/gnvedxo3/)? – Teemu

回答

0

您需要调用绑定,这样的范围不是文档。

document.addEventListener("keydown", this.keyDownHandler.bind(this), false); 
document.addEventListener("keyup", this.keyUpHandler.bind(this), false); 

,并取决于它如何被初始化,它实际上可能是

document.addEventListener("keydown", this.inputs.keyDownHandler.bind(this), false); 
document.addEventListener("keyup", this.inputs.keyUpHandler.bind(this), false); 
+0

我不认为可以这样。在原始代码中(OP表示*工作*),'this'没有被覆盖,所以当事件处理程序被触发时,这两个版本的代码应该有'this'等于'document'(因为事件处理程序被调用在它们所绑定的对象的上下文中)。 – Quentin

+0

在最初的代码中,我没有使用'this'做任何事情。我会尝试一些绑定选项,看看有什么作用。 – Chrinkus

+0

因此,传递'this'引用作为方法的参数不保持对父对象的引用?以为我会很好,直到我进入内部函数的主体。 啊......我没有输入,但keyHandlers的新迭代有'this'引用。 – Chrinkus