使用此

时间:2017-10-29 16:34:05

标签: javascript html css canvas

当我在对象中添加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用于许多其他函数。那我的问题在哪里?

3 个答案:

答案 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)