简体   繁体   English

使用循环删除事件侦听器仅删除最后一个元素的侦听器

[英]Removing event listener using loop removes only last element's listener

I have 3 elemenets in HTML collection and attach onclick listeners to them using forEach loop我在 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);
}

Adding listeners works fine, however when I try to remove them in the same way, only the last element's listener is removed.添加侦听器可以正常工作,但是当我尝试以相同方式删除它们时,只会删除最后一个元素的侦听器。 If I alter the function like this, i get the same result.如果我像这样更改 function,我会得到相同的结果。

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);
}

Can someone explain this?有人可以解释一下吗?

You can use an element's dataset object to pass parameters of type string to the event handler.您可以使用元素的dataset object 将string类型的参数传递给事件处理程序。

Obviously attempts to place parameters on the function object will simply over-write a property of the same name, and the .bind method does not return the function it was called on.显然试图在 function object 上放置参数会简单地覆盖同名的属性,并且.bind方法不会返回 function 它被调用。 Attempts to pass parameters in a closure or by calling bind will result in multiple handler function objects.尝试在闭包中传递参数或通过调用bind将导致多个处理程序 function 对象。

An untested example of the dataset approach: 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM