当我在对象中添加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
});
它可以工作,但只有当我使用 getElementById 查找我的canvas元素,然后根据我的需要使用 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 根本没有改变,我的调试器告诉你:“未捕获的TypeError:无法在 HTMLCanvasElement 读取未定义的属性' getBoundingClientRect ' “。我在这部分代码之前已经在我的对象中声明了canvas,并且我将this.canvas用于许多其他函数。那我的问题在哪里?
答案 0 :(得分:2)
在回调闭包中,this
的上下文是canvas元素本身。因此,您只需使用this
来引用画布。
this.canvas.addEventListener('mousemove', function (e) {
myGameArea.x = (e.clientX - this.getBoundingClientRect().left);
myGameArea.y = (e.clientY - this.getBoundingClientRect().top);
});
答案 1 :(得分: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
。但是,这不是最佳做法。处理嵌套作用域的推荐方法是将bind
函数添加到所需的上下文中:
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,请使用胖箭头表示法(() => {}
),它不会为处理程序创建自己的上下文:
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
});
答案 2 :(得分:0)
在<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="myApp"
android:versionCode="5"
android:versionName="2" >
<uses-sdk android:minSdkVersion="7" />
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".Main"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".DisplayForm"
class=".Aarti" >
</activity>
</application>
</manifest>
的回调函数中,addEventListener
不再是回调之外的值。如果您想绑定到相同的this
值,可以使用this
或使用arrow func:
.bind(this)