原生JavaScript移除带参数EventListeners失败问题求助
问题根因
你代码中的defineOnMouseMove函数是在click事件回调的内部定义的,每触发一次activeItem的点击事件,都会生成一个全新的defineOnMouseMove函数实例。你绑定mousemove事件时用的是上一次点击生成的函数引用,移除时传入的是本次点击新生成的函数,二者引用地址完全不同,removeEventListener无法匹配到之前绑定的监听器,自然移除失效。
事件监听器的匹配规则是:必须同时满足事件类型一致、函数引用完全相同、捕获/冒泡配置一致三个条件,才能成功移除,这也是匿名函数绑定的监听器无法直接移除的核心原因。
修复方案
你只需要把包装后的mousemove监听器引用存到外层作用域,保证绑定和移除时使用的是同一个引用即可,参考修正代码:
let activeItemOnTheMove = false; // 外层作用域存储绑定后的监听器引用 let boundMouseMoveHandler = null; activeItem.addEventListener('click', e => { if (!activeItemOnTheMove) { // 仅首次绑定时创建包装函数 boundMouseMoveHandler = () => onMouseMove(activeItem); document.addEventListener('mousemove', boundMouseMoveHandler); activeItemOnTheMove = true; } else { // 移除时使用之前存储的同一引用 document.removeEventListener('mousemove', boundMouseMoveHandler); activeItemOnTheMove = false; // 可选:清空引用释放内存 boundMouseMoveHandler = null; } }) function onMouseMove(activeItem){ activeItem.style.position = 'absolute'; activeItem.style.left = event.pageX + 'px'; activeItem.style.top = event.pageY + 'px'; activeItem.style.transform = 'translate(-50%,-50%)'; }
你也可以用Function.prototype.bind生成绑定参数后的函数,效果一致:boundMouseMoveHandler = onMouseMove.bind(null, activeItem);
内容的提问来源于stack exchange,提问作者Trying Vlad
相关产品推荐
相关产品推荐

