Javascript:在拖动事件期间类属性变得未定义 [英] Javascript: Class Properties becoming undefined during Drag Events

查看:46
本文介绍了Javascript:在拖动事件期间类属性变得未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Javascript 中的类很陌生,我已经被困了几天试图理解为什么我的属性在我的所有方法中都变得未定义......

我试图将这个复制到一个班级中,但由于我的每次调用方法时都未定义属性.

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

<div class="col" id="container"><div class="card" style="width: 300px; border-top: solid 20px black;"id="拖卡"><div class="card-body"><p>文本</p>

class DragEvents {dragCard = document.querySelector("#dragcard");container = document.querySelector("#container");当前X = 0;当前Y = 0;初始X;初始Y;构造函数(){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);//有效,但我需要在我的方法中使用它.}拖() {console.log("Drag");//触发console.log(this.currentX);//未定义console.log(this.currentY);//未定义console.log(this.initialX);//未定义console.log(this.initialY);//未定义}拖动开始(){console.log("DragStart");//触发}拖动结束(){console.log("DragEnd");//触发}}//结束类var DragEvent = new DragEvents();

解决方案

这是 Web 应用程序开发中的常见问题,尤其是当您尝试使用实例方法作为事件处理程序时.

通常,当你调用类似的东西

instance.method(foo);

函数method被调用,this指向instancefoo作为唯一的参数.这是大多数人期望此代码的行为方式.

然而,instance.method(没有调用)只是对函数的引用.如果你这样做了:

const bar = instance.method;酒吧(富);

您会看到不同的行为.在这种情况下,bar 被调用,this 不指向任何内容,foo 作为唯一参数.这是因为函数不再像调用 instance.method(foo);

时那样绑定到 instance

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

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

您传入对 this.dragStart 指向的函数的引用,但与您的类的连接丢失.

有很多方法可以解决这个问题.它们都有效地执行相同的操作,即将事件处理程序绑定到您的类的实例:

箭头函数表达式您可以使用箭头函数表达式来绑定this 对您的班级的价值:

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 方法this 显式绑定到函数引用

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);}

ES6 方法定义您还可以更改定义类方法的方式,以便将函数绑定到类的实例:

class DragEvents {/* ... */拖动 = () =>{/* ... */}dragStart = () =>{/* ... */}dragEnd = () =>{/* ... */}}//结束类

I'm pretty new with classes in Javascript and I've been stuck for a few days trying to understand why my properties are becoming undefined in all of my methods...

I was trying to replicate this into a class, but was unsuccessful since my properties are undefined every-time a method is called.

I could not find a similar issue on stackoverflow, but please link me if there is one as I'm probably not searching the correct question.

<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();

解决方案

This is a common issue in webapp development, especially when you're trying to use instance methods as event handlers.

Normally, when you call something like

instance.method(foo);

The function method is called, with this pointing to instance and foo as the sole parameter. This is how most people expect this code to behave.

However, instance.method (without the invocation) is just a reference to a function. If you did:

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

You would see different behavior. In this case, bar is called with this pointing to nothing and foo as the sole parameter. This is because the function is no longer bound to instance in the way it was when you called instance.method(foo);

This is precisely what is happening when you call

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

You pass in a reference to the function that this.dragStart points to, but the connection to your class is lost.

There are a number of ways around this. They all do the same thing, effectively, which is to bind the event handlers to an instance of your class:

Arrow function expressions You could use arrow function expressions to bind the value of this to your class:

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 method You could also use the bind method to explicitly bind this to the function reference

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);
}

ES6 method definition You can also change how you define your class methods so that the functions are bound to an instance of the class:

class DragEvents {

    /* ... */

    drag = () => { /* ... */ }

    dragStart = () => { /* ... */ }

    dragEnd = () => { /* ... */ }

}//End Class

这篇关于Javascript:在拖动事件期间类属性变得未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆