JavaScript中,类内的removeEventListener无法正常工作

44

我一直在尝试使用es6类,试图设置一个简单的鼠标类。

addEventListener可以工作,但是出于某种原因,我无法使用removeEventListener将其移除。我猜这与上下文绑定有关,但我无法弄清如何解决这个问题。

'use strict'
class Mouser {
    constructor() {
        this.counter = 0
        this.clicked = function (event) {
            this.counter++
            console.log('clicks:', this.counter)
            if (this.counter >= 10) this.remove()
        }
        window.addEventListener('click', this.clicked.bind(this))
    }

    remove() {
        console.log('Removing click listener') // this line runs ..
        window.removeEventListener('click', this.clicked.bind(this))
    }
}

var mouse = new Mouser()
1个回答

92
每次调用this.clicked.bind(this)时,它都会返回一个新的不同函数。因此,你传递给addEventListener()的函数与你传递给removeEventListener()的函数不相同,所以删除操作找不到匹配项,也就没有移除任何内容。你必须同时传递完全相同的函数才能使删除操作起作用。
你需要创建一个本地存储的函数引用,以便可以将相同的引用传递给add和remove方法。有许多方法可以做到这一点,但由于这是面向对象的代码,所以你将希望将引用存储在对象本身中,以便每个对象都可以拥有自己的引用。
以下是一种方法:
'use strict'
class Mouser {
  constructor () {
    this.counter = 0
    this.clicked = function (event) {
      this.counter ++
      console.log('clicks:', this.counter)
      if (this.counter >= 10) this.remove()
    }
    // save the click handler so it can be used in multiple places
    this.clickHandler = this.clicked.bind(this);
    window.addEventListener('click', this.clickHandler)
  }

  remove () {
    console.log('Removing click listener') // this line runs ..
    window.removeEventListener('click', this.clickHandler)
  }
}

var mouse = new Mouser()

3
谢谢!我正在使用React,这迫使我在很多地方使用bind(this),这真的让我感到困惑。 - DougieHauser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接