javascript:如何使用类方法在类中添加事件处理程序作为回调?

bor*_*ser 6 javascript oop event-handling

如何使用类方法作为回调在类中添加事件处理程序?

<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>
Run Code Online (Sandbox Code Playgroud)

是的我知道一些让它工作的怪癖,但是当这些事件处理程序被引入时会有什么方法?我再次感到痛苦,没有人真正生活在oop :-(

在这里你可以玩:https://jsfiddle.net/sepfsvyo/1/

ibr*_*rir 16

this事件侦听器回调中会引发该事件的元素.如果你想this成为你的类的实例,那么:

将函数绑定到类实例:

使用Function.prototype.bind,将创建一个新函数,其this值始终是您指定的值(类实例):

r.addEventListener('mouseover', this.OnEvent.bind(this));
//                                          ^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

将函数包装在一个非常有用的函数中:

var that = this;
r.addEventListener('mouseover', function(ev) { that.OnEvent(ev); });
//                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

或使用箭头功能(所以不需要that):

r.addEventListener('mouseover', ev => this.OnEvent(ev));
//                              ^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

注意:正如下面的评论中所提到的,上述两种方法都传递了一个不同的函数addEventListener(bind创建一个新函数的函数,显然是一个非常大的函数!== this.OnEvent).如果您稍后要删除事件侦听器,则必须存储对该函数的引用:

var reference;
r.addEventListener('mouseover', reference = this.OnEvent.bind(this));
//                              ^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

要么:

var reference;
var that = this;
r.addEventListener('mouseover', reference = function(ev) { that.OnEvent(ev); });
//                              ^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

然后你可以删除事件监听器,如:

r.removeEventListener('mouseover', reference);
Run Code Online (Sandbox Code Playgroud)


小智 11

您实际上可以将对象作为 EventListener 回调返回,这样 JS 将handleEvent在类中搜索一个方法并相应地执行:

var myInstance = new myClass;
myInstance.addEventListener("mousedown",myInstance);

//To remove the event you can follow the same pattern
myInstance.removeEventListener("mousedown",myInstance);
Run Code Online (Sandbox Code Playgroud)

你必须这样构造你的类:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

来源:

https://medium.com/@WebReflection/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38

https://www.thecssninja.com/javascript/handleevent

https://metafizzy.co/blog/this-in-event-listeners/

我发现这个方法更清晰,同时在类中声明事件this也非常明确。希望我帮助了某人。