javascript removeEventListener not working inside a class

peonicles picture peonicles · Nov 22, 2015 · Viewed 8.5k times · Source

I've been playing around with es6 classes, and tried setting up a simple mouse class.

addEventListener works, but for some reason I'm unable to remove them with removeEventListener. I'm guessing this has something to do with context binding, but I can't figure out how to fix this.

'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()

Answer

jfriend00 picture jfriend00 · Nov 22, 2015

Each time you call this.clicked.bind(this), it returns a new and different function. Thus, the function you are passing to addEventListener() is not the same as the function you are passing to removeEventListenter() so thus the remove does not find a match and does not remove anything. You must pass the exact same function to both for the remove to work.

You will have to create a locally stored reference to the function you're using so that you can pass the same one to add and remove. There are a number of ways to do that, but since this is object oriented code, you will want to store the reference in the object itself so each object can have its own reference.

Here's one way to do that:

'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()