2016-09-28 79 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