removeEventListener 不起作用,尽管函数和目标与 addEventListener 中的函数和目标相同



考虑以下代码:

switch(checkState) {
case 0: pixel.addEventListener('mouseover', addColor);
console.log("test");
break;
case 1: pixel.removeEventListener('mouseover', addColor);
console.log("test2");
break;
}

包含此 switch 语句的函数在其他事件上调用,如果 checkState === 0,则应添加侦听器,或者在 checkState === 1 时删除侦听器。但是侦听器不会在 checkState === 1 上被删除,尽管控制台中显示了"test2"。

我确保:

  • addColor 是一个声明的函数(因此 addEvent 和 removeEvent 都引用同一个函数);
  • 两个处理程序都引用相同的 DOM 元素;
  • 不使用 .bind 方法。

我也深入研究了这个话题,但不幸的是没有找到解决方案。

这是一个回复。

谢谢你的时间。

addColor()函数声明移到checkHover()函数之外:

function addColor ({target}) { target.style.backgroundColor = 'black'; }
function checkHover(pixel) {
switch (checkState) {
case 0: pixel.addEventListener('mouseover', addColor);
console.log("test");
break;
case 1: pixel.removeEventListener('mouseover', addColor);
console.log("test2");
break;
}
}

通过在checkHover()函数中声明它,将创建一个新函数,因此不会引用以前添加的旧函数。


不删除以前添加的处理程序:

const pixel = document.querySelector('div');
const btn = document.querySelector('button');
let checkState = 0;
btn.addEventListener('click', function ({target}) {
checkState = 1;
checkHover(pixel);
})
checkHover(pixel);
function checkHover(pixel) {
// NOT HERE
let addColor = function() { pixel.style.backgroundColor = 'black'; }
switch (checkState) {
case 0: pixel.addEventListener('mouseover', addColor);
console.log("test");
break;
case 1: pixel.removeEventListener('mouseover', addColor);
console.log("test2");
break;
}
}
<button>click first — does not remove listener</button>
<div>hey</div>

删除以前添加的处理程序:

const pixel = document.querySelector('div');
const btn = document.querySelector('button');
let checkState = 0;
btn.addEventListener('click', function ({target}) {
checkState = 1;
checkHover(pixel);
})
checkHover(pixel);
// HERE
function addColor ({target}) { target.style.backgroundColor = 'black'; }
function checkHover(pixel) {

switch (checkState) {
case 0: pixel.addEventListener('mouseover', addColor);
console.log("test");
break;
case 1: pixel.removeEventListener('mouseover', addColor);
console.log("test2");
break;
}
}
<button>click first — does remove listener</button>
<div>hey</div>

还有另一种方法不需要您删除侦听器。

为了方便起见,我在这里使用了CSS Grid。网格中的所有框都使用white类进行初始化。将三个侦听器附加到网格元素(事件委托) -mousedownmouseupmousemove

如果触发mousedown事件,则会true设置down标志。如果触发mouseupdown设置为false。如果触发mousemove并且downtrue则选中该框是否为白色,然后设置新样式。

其他一切都由 CSS 处理。

// Initialise the grid element
const grid = document.querySelector('.grid');
// Initialise the listeners on the grid element
['mousedown', 'mouseup', 'mousemove'].forEach(e => {
grid.addEventListener(e, handleMouse);
});
// Create a grid of boxes initialising them with a white class
function createGrid(gridNumber) {
for (let i = 1; i <= gridNumber * gridNumber; i++) {
const box = document.createElement('div');
box.classList.add('box', 'white');
grid.appendChild(box);
}
}
createGrid(16);
// Initialise the `down` flag
let down = false;
// Check for the events, setting the `down` flag
// for `mousedown/up`, and if the `mousemove` event
// fires and `down` is `true` then set the box style
function handleMouse(e) {
if (e.type === 'mousedown') down = true;
if (e.type === 'mouseup') down = false;
if (e.type === 'mousemove' && down) {
if (e.target.matches('.box.white')) {
e.target.classList.remove('white');
e.target.classList.add('black');
}
}
}
.container { display: flex; flex-direction: column; align-items: center; justify-content: center; margin: 0 0 2em 0; }
.grid { display: grid; grid-template-columns: repeat(16, 1fr); border: 1px solid lightgray; gap: 0;}
.box { height: 20px; width: 20px; }
.box:hover { cursor: pointer; }
.black { background-color: black; }
<div class="container">
<div class="grid"></div>
</div>

相关内容

  • 没有找到相关文章

最新更新