admin管理员组文章数量:1290230
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);
});
}
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);
});
}
Share
Improve this question
edited Jan 24, 2018 at 3:41
Rob
15.2k30 gold badges48 silver badges73 bronze badges
asked Jan 24, 2018 at 3:29
sethWsethW
1852 silver badges9 bronze badges
4
- 1 Arrow functions are anonymous and cannot be back referenced but the 2nd argument to removeEventListener() must be a function reference. – marekful Commented Jan 24, 2018 at 3:32
- Because you're attaching functions that you don't keep a reference to, about all you can do is a deep clone and replace the node with the clone. That will remove all listeners added using addEventListener, but not inline listeners. – RobG Commented Jan 24, 2018 at 3:36
-
In order for
removeEventListener
to work, you have to pass it the same function that you passed intoaddEventListener
, not just one with the same code. – JLRishe Commented Jan 24, 2018 at 3:37 - Don't trust w3schools, the site has many errors, use MDN instead. You can remove anonymous functions, you just have to keep a reference to them. – RobG Commented Jan 24, 2018 at 3:49
3 Answers
Reset to default 6The 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>
In order for removeEventListener
to work, you have to pass it the same function that you passed into addEventListener
, not just one that looks like it.
A plication in what you're trying to do is the use of the closure variable name
, which creates a situation where each separate handler function is a unique, anonymous function, so that would leave you having to keep track of all the functions you used and then reference them again in order to remove the handlers.
But that's really not needed here. name
is just a reference to the element itself, which you can obtain from the event parameters (e.target
).
And if you do that, you can just use an ordinary, named function instead of creating a separate function for each element and having to keep track of them:
let names = document.querySelectorAll('.playerName');
// placeholder
const selectSelf = (el) => console.log(el.textContent);
const clickHandler = (e) => {
selectSelf(e.target);
};
names.forEach((name) => {
name.addEventListener('click', clickHandler);
});
function dropEvents() {
names.forEach((drop) => {
drop.removeEventListener('click', clickHandler);
});
}
document.getElementById('drop').addEventListener('click', dropEvents);
<div class="playerName">Glorgon</div>
<div class="playerName">Marlbratt</div>
<div class="playerName">Xaxir</div>
<div class="playerName">Splengraf</div>
<button type="button" id="drop">Drop Events</button>
本文标签: javascriptRemoving all eventListeners by classStack Overflow
版权声明:本文标题:javascript - Removing all eventListeners by class - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741494154a2381758.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论