Sven Sven - 5 months ago 9
Javascript Question

Removing a JavaScript event: Why is this example not working?

I am struggling with removing a JavaScript event that has previously been added to a DOM element wit

element.addEventListener
:

$(() => {
var example = {
init() {
this.element = document.getElementById('foo');
this.element.addEventListener('mousedown', this.start.bind(this));
},
start() {
console.log('start');
this.element.addEventListener('mouseup', this.stop.bind(this));
},
stop() {
console.log('stop');
this.element.removeEventListener('mouseup', this.stop);
}
};

var bar = Object.create(example);
bar.init();
});


Fiddle

When clicking the element and holding the mousebutton, 'start' is logged. As soon as the mousebutton is released 'stop' is logged. The first time this works as intended, but the second time 'stop' is logged two times, then three times, then four times... What this means is that in
stop()
, the event is not properly removed.

I know that I have to pass the exact same instance to
removeEventListener
I passed to
addEventListener
, but to me this seems correct in this case, so I am a bit lost why this isn't working properly.

Answer

It doesn't work because bind returns a new function, which is different from your original one. You're adding one as a handler but trying to remove a different one. Even if you bound it again to the same this argument, I don't think the return value is guaranteed to be the same.

You need to store the return value of bind of somewhere and use it for both adding and removing the event handler.