使用循环删除事件侦听器只会删除最后一个元素的侦听器
Removing event listener using loop removes only last element's listener
我在 HTML 集合中有 3 个元素,并使用 forEach 循环将 onclick 侦听器附加到它们
[].forEach.call(signBoxes, (e, i) => {
e.addEventListener("click", callSetSign = () => setSign(signs[i]));
});
function setSign({ name, src }) {
const sign = name;
const Img = src;
player1Choice.src = Img;
[].forEach.call(signBoxes, (e, i) => {
e.removeEventListener("click", callSetSign);
});
socket.emit("self-choose-sign", sign);
}
添加侦听器工作正常,但是当我尝试以相同的方式删除它们时,只删除了最后一个元素的侦听器。如果我像这样改变函数,我会得到相同的结果。
function setSign({ name, src }) {
const sign = name;
const Img = src;
player1Choice.src = Img;
signBoxes[0].removeEventListener('click', callSetSign)
signBoxes[1].removeEventListener('click', callSetSign)
signBoxes[2].removeEventListener('click', callSetSign) // only this one works
socket.emit("self-choose-sign", sign);
}
谁能解释一下?
您可以使用元素的 dataset
对象将 string
类型的参数传递给事件处理程序。
显然,尝试在函数对象上放置参数只会覆盖同名的 属性,并且 .bind
方法不会 return 调用它的函数在。尝试在闭包中或通过调用 bind
传递参数将导致多个处理函数对象。
dataset
方法的一个未经测试的例子:
[].forEach.call(signBoxes, (e, i) => {
e.dataset.index = i; // store index on element
e.addEventListener("click", setSign);
});
function setSign() {
const { name, src } = signs[this.dataset.index];; // lookup using index
const sign = name;
const Img = src;
player1Choice.src = Img;
[].forEach.call(signBoxes, (e, i) => {
e.removeEventListener("click", setSign);
});
socket.emit("self-choose-sign", sign);
}
我在 HTML 集合中有 3 个元素,并使用 forEach 循环将 onclick 侦听器附加到它们
[].forEach.call(signBoxes, (e, i) => {
e.addEventListener("click", callSetSign = () => setSign(signs[i]));
});
function setSign({ name, src }) {
const sign = name;
const Img = src;
player1Choice.src = Img;
[].forEach.call(signBoxes, (e, i) => {
e.removeEventListener("click", callSetSign);
});
socket.emit("self-choose-sign", sign);
}
添加侦听器工作正常,但是当我尝试以相同的方式删除它们时,只删除了最后一个元素的侦听器。如果我像这样改变函数,我会得到相同的结果。
function setSign({ name, src }) {
const sign = name;
const Img = src;
player1Choice.src = Img;
signBoxes[0].removeEventListener('click', callSetSign)
signBoxes[1].removeEventListener('click', callSetSign)
signBoxes[2].removeEventListener('click', callSetSign) // only this one works
socket.emit("self-choose-sign", sign);
}
谁能解释一下?
您可以使用元素的 dataset
对象将 string
类型的参数传递给事件处理程序。
显然,尝试在函数对象上放置参数只会覆盖同名的 属性,并且 .bind
方法不会 return 调用它的函数在。尝试在闭包中或通过调用 bind
传递参数将导致多个处理函数对象。
dataset
方法的一个未经测试的例子:
[].forEach.call(signBoxes, (e, i) => {
e.dataset.index = i; // store index on element
e.addEventListener("click", setSign);
});
function setSign() {
const { name, src } = signs[this.dataset.index];; // lookup using index
const sign = name;
const Img = src;
player1Choice.src = Img;
[].forEach.call(signBoxes, (e, i) => {
e.removeEventListener("click", setSign);
});
socket.emit("self-choose-sign", sign);
}