How do i add an event handler inside a class with a class-method as the callback ???
<div id="test">move over here</div>
<script>
oClass = new CClass();
function CClass()
{
this.m_s = "hello :-/";
this.OnEvent = OnEvent;
with(this)
{
var r = document.getElementById("test");
r.addEventListener('mouseover', this.OnEvent); // this does NOT work :-/
}
function OnEvent()
{
alert(this); // this will be the HTML div-element
alert(this.m_s); // will be undefined :-()
}
}
</script>
Yes i know some quirks to make it work but what would be the intended way when these event handlers were introduced ??? I again have the bitter feeling, that no-one truly lives oop :-(
Here for you to play: https://jsfiddle.net/sepfsvyo/1/
The this
inside the event listener callback will be the element that fired the event. If you want the this
to be the instance of your class, then either:
Bind the function to the class instance:
Using Function.prototype.bind
, will create a new function that its this
value will always be what you specify it to be (the class instance):
r.addEventListener('mouseover', this.OnEvent.bind(this));
// ^^^^^^^^^^^
Wrap the function inside an anounimous function:
var that = this;
r.addEventListener('mouseover', function(ev) { that.OnEvent(ev); });
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
or use an arrow function (so no need for that
):
r.addEventListener('mouseover', ev => this.OnEvent(ev));
// ^^^^^^^^^^^^^^^^^^^^^^
Note: As mentioned in a comment bellow, both of the above methods pass a different function to addEventListener
(the one with bind
create a new function, and the anounimous function is obviously !== this.OnEvent
). If you are going to remove the event listener later, you'll have to store a reference to the function:
var reference;
r.addEventListener('mouseover', reference = this.OnEvent.bind(this));
// ^^^^^^^^^^^^
or:
var reference;
var that = this;
r.addEventListener('mouseover', reference = function(ev) { that.OnEvent(ev); });
// ^^^^^^^^^^^^
then you can remove the event listener like:
r.removeEventListener('mouseover', reference);
You can actually return the object as an EventListener callback, this way JS will search for an handleEvent
method in the class and execute accordingly :
var myInstance = new myClass;
myInstance.addEventListener("mousedown",myInstance);
//To remove the event you can follow the same pattern
myInstance.removeEventListener("mousedown",myInstance);
You have to construct your class this way :
Class myClass
constructor(){
//Whatever this is supposed to do.
//You can also add events listener within the class this way :
this.addEventListener("mousedown",this);
}
mouseDownEvent(e)(){
//Some action related to the mouse down event (e)
console.log(e.target);
}
mouseMoveEvent(e)(){
//Some action related to the mouse move event (e)
}
mouseUpEvent(e)(){
//Some action related to the mouse up event (e)
}
handleEvent(e) {
switch(e.type) {
case "mousedown":
this.mouseDownEvent(e);
break;
case "mousemove":
this.mouseMoveEvent(e);
break;
case "mouseup":
this.mouseUpEvent(e);
break;
}
}
Sources :
https://www.thecssninja.com/javascript/handleevent
https://metafizzy.co/blog/this-in-event-listeners/
I find this method clearer, also while declaring events inside the class this
is pretty explicit.
Hope I helped someone.
来源:https://stackoverflow.com/questions/43727516/javascript-how-adding-event-handler-inside-a-class-with-a-class-method-as-the-c