首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在使用class-method作为回调的类中添加事件处理程序?

如何在使用class-method作为回调的类中添加事件处理程序?
EN

Stack Overflow用户
提问于 2017-05-02 06:39:59
回答 3查看 26.9K关注 0票数 24

如何在使用class-method作为回调的类中添加事件处理程序?

代码语言:javascript
运行
复制
<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>

是的,我知道一些让它工作的怪癖,但是当这些事件处理程序引入时,预期的方式是什么?我又有一种苦涩的感觉,没有人真正活着。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-05-02 06:47:12

事件侦听器回调中的this将是触发事件的元素。如果希望this成为类的实例,则可以:

将函数绑定到类实例:

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

代码语言:javascript
运行
复制
r.addEventListener('mouseover', this.OnEvent.bind(this));
//                                          ^^^^^^^^^^^

将函数包装在匿名函数中:

代码语言:javascript
运行
复制
var that = this;
r.addEventListener('mouseover', function(ev) { that.OnEvent(ev); });
//                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

或者使用arrow function (所以不需要that):

代码语言:javascript
运行
复制
r.addEventListener('mouseover', ev => this.OnEvent(ev));
//                              ^^^^^^^^^^^^^^^^^^^^^^

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

代码语言:javascript
运行
复制
var reference;
r.addEventListener('mouseover', reference = this.OnEvent.bind(this));
//                              ^^^^^^^^^^^^

或者:

代码语言:javascript
运行
复制
var reference;
var that = this;
r.addEventListener('mouseover', reference = function(ev) { that.OnEvent(ev); });
//                              ^^^^^^^^^^^^

然后,您可以删除事件侦听器,如下所示:

代码语言:javascript
运行
复制
r.removeEventListener('mouseover', reference);
票数 46
EN

Stack Overflow用户

发布于 2019-09-29 02:50:37

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

代码语言:javascript
运行
复制
var myInstance = new myClass;
myInstance.addEventListener("mousedown",myInstance);

//  To remove the event you can follow the same pattern
myInstance.removeEventListener("mousedown",myInstance);

你必须这样构造你的类:

代码语言:javascript
运行
复制
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;
        }
    }
}

资料来源:

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中声明事件也非常明确。希望我帮了什么人。

票数 12
EN

Stack Overflow用户

发布于 2021-11-13 08:45:47

来自@ibrahimmahrir的答案可以完成这项工作,但我想巩固几点。

正如许多JavaScript开发人员难以理解的那样,this关键字是一个不断变化的目标。在传统的OOP语言中,对象方法是对象所独有的,因此this被定义为它所附加到的对象。

JavaScript函数更加混杂,并且可以附加到多个对象。在JavaScript中,this指的是当前正在调用函数的对象,而不一定是函数最初附加到的对象。

对于事件处理程序函数,调用对象是它附加到的元素,而不是原始对象;因此this指的是元素。通常的安全方法是将对原始对象的引用存储在另一个变量中,该变量通常称为that

代码语言:javascript
运行
复制
oClass = new CClass();
function CClass() {
    var that = this;        //  a reference to the original object
    this.m_s = "hello :-/";
    this.OnEvent = OnEvent;
    var r = document.getElementById("test");
    r.addEventListener('click', this.OnEvent);

    function OnEvent() {
        alert(that);        //  this is now the object
        alert(that.m_s);    //  this works
    }
}

上面的评论是我的更新评论。我还删除了with语句,该语句贡献不大,并且严重不鼓励使用。

哦,为了更容易测试,我已经将事件更改为click

虽然我们对this感到困惑,但它不一定是开始事情的元素。假设我们现在包含了一个span

代码语言:javascript
运行
复制
<div id="test">click <span>over</span> here</div>

单击span将触发事件侦听器,即使您实际上没有单击它所附加到的div。在这种情况下,事件是从span到div冒泡的。

在这里,this只引用带有事件侦听器的div元素。如果要引用span,则需要event.target

代码语言:javascript
运行
复制
function OnEvent(event) {   //  include event parameter
    alert(this);            //  the element attached
    alert(event.target);    //  the element clicked
    alert(that);            //  this is now the object
    alert(that.m_s);        //  this works
}

这是一个更新的提琴:https://jsfiddle.net/osk083xv/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43727516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档