I am using the first code block to successfully add eventListeners to a group of <div>
tags with the same class, but the second block, which is almost identical, does not remove them. Can someone explain why this is?
1.
let names = document.querySelectorAll('.playerName');
names.forEach((name) => {
name.addEventListener('click', () => {selectSelf(name)});
});
2.
function dropEvents() {
let drops = document.querySelectorAll('.playerName');
drops.forEach((drop) => {
drop.removeEventListener('click', () => {selectSelf(name)});
});
}
They are both selecting the same group of <div>
tags with class .playerName
. The selectSelf(name)
function that runs on click
only assigns the value of the clicked <div>
to a variable, runs an alert()
(just so I can know it successfully ran) and then immediately calls the dropEvents()
function. So in theory selectSelf(name)
shouldn't run after the first time, but it does.
For the .removeEventListener
method, I've tried many different variations with no success.
EDIT: I saw on the w3schools page for this method that anonymous functions won't work, which sorta changes my question. I tried the following, but it didn't work either.
function dropEvents() {
let drops = document.querySelectorAll('.playerName');
drops.forEach((drop) => {
drop.removeEventListener('click', selectSelf);
});
}
The 2nd argument to removeEventListener() must be a reference to the function that is assigned to the event as listener but you are passing a new, literal arrow function.
In the example, the 2nd occurrence of () => {selectSelf(name)}
is a new arrow function declared literally. The one that was already added as an event handler is a different function so you cannot expect it to be removed.
To make it work, save a reference to each handler function that you can later pass to removeEventListener()
:
let names = document.querySelectorAll('.playerName');
const handlers = [];
names.forEach((name) => {
// Use a unique identifier for each function reference
handlers[name.id] = () => selectSelf(name);
name.addEventListener('click', handlers[name.id]);
});
function dropEvents() {
let drops = document.querySelectorAll('.playerName');
drops.forEach((drop) => {
drop.removeEventListener('click', handlers[drop.id]);
});
}
The signature / reference of the event handler must be the same. In your code, during remove, you must refer to the same function. Below is the solution. Move the click
event handler to a function.
let names = document.querySelectorAll('.playerName');
const clickEv = () => {
// selectSelf(name);
console.log('yay');
};
names.forEach((name) => {
name.addEventListener('click', clickEv);
});
function dropEvents() {
let drops = document.querySelectorAll('.playerName');
drops.forEach((drop) => {
drop.removeEventListener('click', clickEv);
});
}
<button type="button" class="playerName">1</button>
<button type="button" class="playerName">2</button>
<button type="button" class="playerName">3</button>
<button type="button" class="playerName">4</button>
<button type="button" class="drop" onClick="dropEvents()">drop</button>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With