Javascript:类属性在拖动事件期间变得未定义

问题描述 投票:0回答:1

我对Javascript类非常陌生,为了了解为什么我的属性在所有方法中都变得不确定,我被困了几天。

我试图将this复制到一个类中,但是没有成功,因为每次调用一个方法时,我的属性都是未定义的。

我在stackoverflow上找不到类似的问题,但是如果有一个问题,请链接我,因为我可能没有搜索正确的问题。

<div class="row" style="height: 800px;">
    <div class="col" id="container">
        <div class="card" style="width: 300px; border-top: solid 20px black;" id="dragcard">
            <div class="card-body">
                <p>Text</p>
            </div>
        </div>
    </div>
</div>
class DragEvents {

    dragCard = document.querySelector("#dragcard");
    container = document.querySelector("#container");

    currentX = 0;
    currentY = 0;
    initialX;
    initialY;

    constructor() {

        this.container.addEventListener("mousedown", this.dragStart, false);
        this.container.addEventListener("mouseup", this.dragEnd, false);
        this.container.addEventListener("mousemove", this.drag, false);

        console.log(this.currentX);//works, but I need this to work in my methods.
    }

    drag() {
        console.log("Drag");//fires
        console.log(this.currentX);//undefined
        console.log(this.currentY);//undefined
        console.log(this.initialX);//undefined
        console.log(this.initialY);//undefined
    }

    dragStart() {
        console.log("DragStart");//fires
    }

    dragEnd() {
        console.log("DragEnd");//fires
    }

}//End Class
var DragEvent = new DragEvents();
javascript class draggable addeventlistener
1个回答
1
投票

这是webapp开发中的常见问题,尤其是当您尝试将实例方法用作事件处理程序时。

通常,当您打电话给类似的人时>

instance.method(foo);

将调用method函数,其中this指向instance,而foo是唯一的参数。这就是大多数人期望此代码表现出来的方式。

但是,instance.method(不进行调用)只是对函数的引用。如果您这样做:

const bar = instance.method;
bar(foo);

您会看到不同的行为。在这种情况下,将调用bar,其中this指向无内容,而foo作为唯一参数。这是因为该函数不再像调用instance时那样绑定到instance.method(foo)

这正是您打电话时发生的事情

this.container.addEventListener("mousedown", this.dragStart, false);

您传递了对this.dragStart所指向的函数的引用,但是与您的类的连接丢失。

有多种解决方法。它们都有效地执行了相同的操作,即将事件处理程序绑定到您的类的实例:

箭头函数表达式

您可以使用arrow function expressionsthis的值绑定到您的课程:
constructor() {
  this.container.addEventListener("mousedown", (e) => this.dragStart(e), false);
  this.container.addEventListener("mouseup", (e) => this.dragEnd(e), false);
  this.container.addEventListener("mousemove", (e) => this.drag(e), false);
}

绑定方法

您也可以使用bind methodbind明确绑定到函数引用
this

ES6方法定义

您还可以更改定义类方法的方式,以便将函数绑定到类的实例:
constructor() {
  this.container.addEventListener("mousedown", this.dragStart.bind(this), false);
  this.container.addEventListener("mouseup", this.dragEnd.bind(this), false);
  this.container.addEventListener("mousemove", this.drag.bind(this), false);
}
© www.soinside.com 2019 - 2024. All rights reserved.