繁体   English   中英

JavaScript 删除 IIFE 事件侦听器

[英]JavaScript remove an IIFE event listener

在使用这样的 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]);
        }
    }
}

该函数在(clickSquare)(i)处被立即调用。 在问题的代码中allSquares似乎是元素本身,可以直接引用clickSquare函数,并且可以在事件处理程序中使用event.target来引用allSquares集合中的当前元素

 let player = 123; setInterval(() => player = Math.random(), 1000); onload = () => { let allSquares = document.querySelectorAll("div[id|=square]"); let button = document.querySelector("button"); button.onclick = removeClickEvents; function setupPlayer(player) { var squareState = {}; for (let i = 0; i < allSquares.length; i++) { if (allSquares[i].innerHTML === "click") { // set up a click event for each square allSquares[i].addEventListener('click', clickSquare); } } } function clickSquare(event) { console.log(event.target); event.target.innerHTML = player; } function removeClickEvents() { for (let i = 0; i < allSquares.length; i++) { allSquares[i].removeEventListener('click', clickSquare); } } setupPlayer(player); }
 <div id="square-0">click</div> <div id="square-1">click</div> <div id="square-2">click</div> <button>remove events</button>

暂无
暂无

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

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