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

document.addEventListener("keydown", this.inputs.keyDownHandler.bind(this), false); document.addEventListener("keyup", this.inputs.keyUpHandler.bind(this), false); 
ましたそれらの人は正しいです。 (あなたのテストケースでは、あなたは決して '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); 

、それが初期化された方法に応じて、それが実際にあるかもしれない

私はいくつかの理由を考えることができますが、[MCVE]私は言うことはできません提供していない
+0

私はそれが事実であるとは思わない。元のコード(OPが*働いていた*)では、 'this'はオーバーライドされていなかったので、イベントハンドラがトリガされたときにコードの両方のバージョンが' this'を 'document'と同じにする必要がありますそれらが結ばれているオブジェクトの文脈で)。 – Quentin

+0

元のコードでは、私は何のために 'this'を使っていませんでした。バインドオプションのいくつかを試してみて、何がうまくいくか見てみましょう。 – Chrinkus

+0

したがって、メソッドからの引数として 'this'参照を渡すことは、親オブジェクトへの参照を維持しませんか?私が内部機能の体に入るまでは、私はうまくいくと思った。 Ahhh ..私はそれをタイプしませんでしたが、keyHandlerの新しい反復には 'this'の参照があります。 – Chrinkus

関連する問題