我试图在添加像这样的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无效。
答案 0 :(得分:4)
要从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]);
}
}
}
答案 1 :(得分:0)
正在(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);
}
&#13;
<div id="square-0">click</div>
<div id="square-1">click</div>
<div id="square-2">click</div>
<button>remove events</button>
&#13;