Javascript:在拖动事件期间类属性变得未定义 [英] Javascript: Class Properties becoming undefined during Drag Events
问题描述
我对 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
指向instance
,foo
作为唯一的参数.这是大多数人期望此代码的行为方式.
然而,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屋!