2017-10-29 7 views
0

以下は、私は私のオブジェクトでのEventListenerを追加したときに私のコードです:は使用してオブジェクトに機能を使用することはできません。この

this.canvas.addEventListener('mousemove', function (e) { 
    var canv = document.getElementById("some"); 
    myGameArea.x = (e.clientX - canv.getBoundingClientRect().left);//Look at canv 
    myGameArea.y = (e.clientY - canv.getBoundingClientRect().top);//Look at canv 
}); 

それは動作しますが、私はその後、私のcanvas要素を見つけるとするgetElementByIdをを使用する場合にのみ使用しますcanv私のニーズに応えます。しかし、私はこれを行う場合:すべての

this.canvas.addEventListener('mousemove', function (e) { 
    var canv = document.getElementById("some"); 
    myGameArea.x = (e.clientX - this.canvas.getBoundingClientRect().left);//Look at this.canvas 
    myGameArea.y = (e.clientY - this.canvas.getBoundingClientRect().top);//Look at this.canvas 
}); 

その後myGameArea doesntの変更をして、私のデバッガはこのことを伝えます: "キャッチされない例外TypeErrorを:。HTMLCanvasElementで未定義のプロパティ 'getBoundingClientRect' を読み取ることができません"。私はコードのこの部分の前に私のオブジェクトにキャンバスを宣言し、私はthis.canvasを他の多くの関数に使用しました。だから私の問題はどこですか?

答えて

1

thisキーワードの値は、関数が、あなたがアクセスしている場所に依存しませんそれは定義されていますが、どのように呼び出されます。あなたのケースでは、thisがハンドラで上書きされています。

var that = this; 
this.canvas.addEventListener('mousemove', function (e) { 
    myGameArea.x = (e.clientX - that.canvas.getBoundingClientRect().left);//Look at this.canvas 
    myGameArea.y = (e.clientY - that.canvas.getBoundingClientRect().top);//Look at this.canvas 
}); 

ここでは、明示的に我々がアクセスしたいオブジェクトを述べるので、まったくthisを使用する必要はありません:迅速な問題を回避するには、次のようになります。ただし、これはベストプラクティスとはみなされません。独自のを作成しません脂肪の矢印表記(() => {})を使用し、

this.canvas.addEventListener('mousemove', function (e) { 
    myGameArea.x = (e.clientX - this.canvas.getBoundingClientRect().left);//Look at this.canvas 
    myGameArea.y = (e.clientY - this.canvas.getBoundingClientRect().top);//Look at this.canvas 
}.bind(this)); 

それとも、あなたはES6を使用している場合:ネストされたスコープに対処するための推奨方法は、あなたがしたいコンテキストにbindへの関数でありますコンテキストは、ハンドラの:コールバッククロージャ内

this.canvas.addEventListener('mousemove', (e) => { 
    myGameArea.x = (e.clientX - this.canvas.getBoundingClientRect().left);//Look at this.canvas 
    myGameArea.y = (e.clientY - this.canvas.getBoundingClientRect().top);//Look at this.canvas 
}); 
+0

ありがとう!それを感謝します! –

+0

@ZaharZagrava嬉しいです。それがあなたを助けたならば、答えは[受け入れられる](https://meta.stackexchange.com/a/5235)としてください。 – stybl

0

addEventListenerのコールバック関数では、thisはもはやコールバックの外にあったのと同じ値ではなくなりました。あなたは.bind(this)または使用の矢印FUNCのいずれかを使用することができ、同じthis値にバインドしたい場合:通常の変数とは異なり

this.canvas.addEventListener('mousemove', function (e) { 
    var canv = document.getElementById("some"); 
    myGameArea.x = (e.clientX - this.canvas.getBoundingClientRect().left);//Look at this.canvas 
    myGameArea.y = (e.clientY - this.canvas.getBoundingClientRect().top);//Look at this.canvas 
}.bind(this)); 

this.canvas.addEventListener('mousemove', (e) => { 
    var canv = document.getElementById("some"); 
    myGameArea.x = (e.clientX - this.canvas.getBoundingClientRect().left);//Look at this.canvas 
    myGameArea.y = (e.clientY - this.canvas.getBoundingClientRect().top);//Look at this.canvas 
}); 
+0

ありがとうございます!しかし、(e)=>はどういう意味ですか?あなたは私にサイトやドキュメンタリーを送ってもらえますか? –

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – hackerrdave

+0

arrow funcsには独自の 'this'がありませんので、' this'はまだその外側のスコープを指しています – hackerrdave

2

thisのコンテキストは、canvas要素そのものです。したがって、キャンバスの参照にはthisを使用するだけです。

this.canvas.addEventListener('mousemove', function (e) { 
    myGameArea.x = (e.clientX - this.getBoundingClientRect().left); 
    myGameArea.y = (e.clientY - this.getBoundingClientRect().top); 
}); 
関連する問題