I’m trying to remove event listeners from elements after they’ve been clicked on and although I seem to have a working solution, it’s not ideal and I’m not sure why it works differently to the broken code.
Although I realise there are simpler ways of doing this, this is taken from a JS class I’m working on so need to retain some of the structure.
This relates to a previous post I made which was answered correctly (but didn’t work when I expanded the example) – Removing event listeners with anonymous function calls in JavaScript.
In this example, the last created div removes the listener correctly but earlier ones don’t (fiddle here – http://jsfiddle.net/richwilliamsuk/NEmbd/):
var ctnr = document.getElementById('ctnr');
var listener = null;
function removeDiv (d) {
alert('testing');
d.removeEventListener('click', listener, false);
}
function addDiv () {
var div = document.createElement('div');
div.innerHTML = 'test';
ctnr.appendChild(div);
div.addEventListener('click', (function (d) { return listener = function () { removeDiv(d); } })(div), false);
}
addDiv();
addDiv();
addDiv();
In the version I got working I create an array which holds all the listeners (fiddle here – http://jsfiddle.net/richwilliamsuk/3zZRj/):
var ctnr = document.getElementById('ctnr');
var listeners = [];
function removeDiv(d) {
alert('testing');
d.removeEventListener('click', listeners[d.id], false);
}
function addDiv() {
var div = document.createElement('div');
div.innerHTML = 'test';
ctnr.appendChild(div);
div.id = listeners.length;
div.addEventListener('click', (function(d) {
return listeners[listeners.length] = function() {
removeDiv(d);
}
})(div), false);
}
addDiv();
addDiv();
addDiv();
document.getElementById('btn').addEventListener('click', function() {
alert(listeners);
}, false);
The final one works fine but I’m sure the listener array shouldn’t be necessary. Maybe I’m worrying too much but I’d like to know the optimal solution.
You have to save each and every listener if they are unequal, so you need a relation between listener and element. Since an element is represented by an object (DOM: document object model) you can add custom properties to them (although it’s not recommended: Can I add arbitrary properties to DOM objects?) (demo):
But since your using the same listener in every div its even better not to use a separate function for every div but the same (demo):