【问题标题】:How do you call a object method from within an addEventListener() call?如何从 addEventListener() 调用中调用对象方法?
【发布时间】:2019-05-06 00:54:04
【问题描述】:

我正在向对象方法内的按钮添加事件侦听器。我正在尝试添加对另一个方法函数的调用,但是当我使用 this.reset() 时,“this”指向侦听器//按钮而不是对象本身。

此代码已被重构为一个对象,并且之前运行良好。在那种情况下,我不需要使用“this”。

const colorGame = {
    reset: function() {...},

    init: function() {
        for (let i = 0; i < modeSwitches.length; i++) {
            modeSwitches[i].addEventListener("click", function() {
                modeSwitches[0].classList.remove('selected');
                modeSwitches[1].classList.remove('selected');

                // These two lines are why I can't use anonymous functions
                this.classList.add('selected'); 
                this.textContent === 'Easy' ? numSquares = 3 : numSquares = 6;
                this.reset();
            });
        }

        ...
    resetButton.addEventListener('click', function() {
            this.reset(); // This call also fails with the same error
});

Chrome 浏览器控制台出错:colorGame.js:78 Uncaught TypeError: this.reset is not a function

我的意图是使用 colorGame.reset() 并在单击按钮时调用它。

【问题讨论】:

    标签: javascript object methods this addeventlistener


    【解决方案1】:

    让你的colorGame 对象实现EventListener 接口,方法是给它一个handleEvent 方法。然后您可以将对象本身绑定为事件处理程序,并在事件发生时调用其handleEvent 方法。

    handleEvent 中this 的值将是colorGame 对象。

    const colorGame = {
      handleEvent: function(event) {
        // handle events here
        switch (event.type) {
          case "click":
            this.reset();
            break;
            
          default:
            console.log("unhandled event type");
        }
      },
    
      reset: function() {
        console.log("reset was called");
      },
    
      // Bind the colorGame object instead of binding functions
      init: function() {
        for (let i = 0; i < modeSwitches.length; i++) {
          modeSwitches[i].addEventListener("click", colorGame);
        }
    
        resetButton.addEventListener('click', colorGame);
      }
    }

    【讨论】:

    • handleEvent 方法是否特殊以允许addEventListener() 绑定到它而不是函数?我以为addEventListener() 的第二个参数是一个函数。
    • 是的,您可以传递任何常规对象而不是函数如果该对象具有(或继承)名为handleEvent 的方法。
    • 简单地说,这是一个很好的解决方案。
    【解决方案2】:

    更改您的事件侦听器以使用匿名函数,例如: modeSwitches[i].addEventListener("click", () =&gt; this.reset()); resetButton.addEventListener('click', () =&gt; this.reset());

    【讨论】:

    • 这是我的代码的一种方式,但是因为我也使用“this”来指代事件侦听器,所以我也会丢失这些部分。编辑要显示的原件。
    • @twodox:那么您只需定义一个event 参数并使用引用该元素的event.currentTarget。你也会对我的回答做同样的事情。在现代 JS 中使用 var that = this; 几乎是闻所未闻的。这是一种不幸的做法,我们已经超越了。不知道为什么它仍然被推荐为一个好的解决方案。
    【解决方案3】:

    只需将this 存储到另一个变量中。我通常称之为that。

    const colorGame = {
    reset: function() {...},
    
    init: function() {
    
        let that = this;
        for (let i = 0; i < modeSwitches.length; i++) {
            modeSwitches[i].addEventListener("click", function() {
                ...
                that.reset();
            });
        }
        ...
        resetButton.addEventListener('click', function() {
            that.reset(); 
        });
    

    【讨论】:

      猜你喜欢
      • 2016-02-11
      • 2011-10-22
      • 2021-12-28
      • 1970-01-01
      • 2022-11-30
      • 2015-03-20
      • 1970-01-01
      • 2016-10-11
      • 2022-12-09
      相关资源
      最近更新 更多