React中使用Highcharts无法移除拖拽功能绑定的事件监听器
Highcharts 3D散点图拖拽事件解绑失效问题修复方案
问题根源
removeEventListener 必须传入和绑定时完全一致的函数引用才能成功移除事件,你的代码中绑定 mousemove、touchmove 等事件时用的是临时生成的匿名箭头函数,解绑时又传入了新的空匿名函数,浏览器无法匹配到要移除的目标事件,因此解绑失效。此外原有逻辑会在每次点击时重复绑定事件,也会导致功能异常。
修复后代码
// 全局存储事件函数引用,确保解绑时用的是同一个函数 let dragHandler = null; let unBindHandler = null; let isDraggingEnabled = false; let isClicked = false; const init = (chart) => { const sensitivity = 4; // 把unBind逻辑提出来,统一维护引用 unBindHandler = (e) => { console.log("mouse up triggered"); e.preventDefault(); e.stopPropagation(); isClicked = false; // 移除所有绑定的移动事件 window.removeEventListener("touchmove", dragHandler); window.removeEventListener("mousemove", dragHandler); window.removeEventListener("mouseup", unBindHandler); window.removeEventListener("touchend", unBindHandler); }; window.addEventListener("click", (eStart) => { // 点击切换拖拽状态 isDraggingEnabled = !isDraggingEnabled; if (!isDraggingEnabled) { // 关闭拖拽时直接触发解绑 unBindHandler(eStart); return; } // 避免重复绑定 if (isClicked) return; isClicked = true; const posX = eStart.chartX, posY = eStart.chartY, alpha = chart.options.chart.options3d.alpha, beta = chart.options.chart.options3d.beta; // 拖拽逻辑赋值给全局维护的变量,保证引用一致 dragHandler = (e) => { const newBeta = beta + (posX - e.pageX) / sensitivity; chart.options.chart.options3d.beta = newBeta; const newAlpha = alpha + (e.pageY - posY) / sensitivity; chart.options.chart.options3d.alpha = newAlpha; chart.redraw(false); }; window.addEventListener("touchmove", dragHandler); window.addEventListener("mousemove", dragHandler); window.addEventListener("mouseup", unBindHandler); window.addEventListener("touchend", unBindHandler); }); };
核心修改点
- 全局存储
dragHandler、unBindHandler两个事件函数的引用,绑定和解绑时都使用同一个引用 - 新增
isDraggingEnabled状态变量实现点击切换拖拽功能的需求,第一次点击开启拖拽,第二次点击关闭 - 所有绑定的事件(触摸移动、鼠标移动、鼠标抬起、触摸结束)都做了对应解绑处理,避免事件残留
- 增加重复绑定判断,防止多次点击触发重复的事件绑定
内容的提问来源于stack exchange,提问作者sara1112
相关产品推荐
相关产品推荐

