JavaScript 删除 IIFE 事件监听器

标签 javascript dom-events

在使用像这样的 IIFE 添加点击事件后,我尝试从 id 列表中删除点击事件

function setupPlayer(player){
  var squareState = {};
  for (i = 0; i < allSquares.length; i++) {
      if(allSquares[i].innerHTML === "") {
        // set up a click event for each square
         document.getElementById(allSquares[i].getAttribute('id')).addEventListener('click', (clickSquare)(i));
      }
    }
}

clickSquare 函数返回

function clickSquare(i){
  var num = i;
  return function() {
      document.getElementById(allSquares[num].getAttribute('id')).innerHTML=player;
  }
}

然后我尝试使用删除它们

function removeClickEvents(){
  for (let i = 0; i < allSquares.length; i++) {
    document.getElementById(allSquares[i].getAttribute('id')).removeEventListener('click', clickSquare);
  }
} 

我尝试命名返回的匿名函数并使用 removeEventListener ,但没有成功。

最佳答案

要从 DOM 元素中删除事件监听器,您需要传递添加事件监听器时使用的相同函数作为参数。

在 JavaScript 中,当您创建一个对象时,它会创建该对象类的一个新实例,因此即使它是使用相同的参数创建的,它也不会等于另一个对象

示例:

{} != {} // returns true
[] != [] // returns true

函数也是如此,每当您编写 function (){} 时,它都会创建 Function 类的新实例。

示例:

function a() {
    return function b() {}
}
a() != a() // returns true

解决方案:

因此,为了能够删除事件监听器,您必须存储传递给 addEventListener

的函数
var listeners = [];

function setupPlayer(player) {
    var squareState = {};
    for (i = 0; i < allSquares.length; i++) {
        if(allSquares[i].innerHTML === "") {
            listeners[i] = clickSquare(i);
            document.getElementById(allSquares[i].getAttribute('id')).addEventListener('click', listeners[i]);
        }
    }
}

function clickSquare(i) {
    var num = i;
    return function() {
        document.getElementById(allSquares[num].getAttribute('id')).innerHTML=player;
    }
}

function removeClickEvents() {
    for (let i = 0; i < allSquares.length; i++) {
        if(listeners[i]) {
            document.getElementById(allSquares[i].getAttribute('id')).removeEventListener('click', listeners[i]);
        }
    }
}

来自您正在使用的代码

document.getElementById(allSquares[i].getAttribute('id'))

我假设 allSquares[i] 已经是一个 DOM 元素,您的代码可以更加简化

var listeners = [];

function setupPlayer(player) {
    var squareState = {};
    for (i = 0; i < allSquares.length; i++) {
        if(allSquares[i].innerHTML === "") {
            listeners[i] = clickSquare(i);
            allSquares[i].addEventListener('click', listeners[i]);
        }
    }
}

function clickSquare(i) {
    var num = i;
    return function() {
        allSquares[num].innerHTML=player;
    }
}

function removeClickEvents() {
    for (let i = 0; i < allSquares.length; i++) {
        if(listeners[i]) {
            allSquares[i].removeEventListener('click', listeners[i]);
        }
    }
}

关于JavaScript 删除 IIFE 事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46514959/

相关文章:

带有图像映射的 JavaScript 事件传播

javascript - Html 5 Canvas 图片库

wordpress - Youtube 视频结束时捕获的 Javascript 事件

javascript - 冲浪后丢失引用创建的窗口

javascript - 如何在 inputText 中显示指定值?(XPages)

javascript - 如何在列表项中垂直居中 FontAwesome 图标?

javascript - mdl-js-ripple-effect 导致 event.target.value 在 React 组件中变为未定义

javascript - 如何在循环中的 Coffeescript 中使用 setTimeout

javascript - Document.write 不工作

javascript - 分配给用作事件处理程序的变量不是 react 性的 :