如何在JavaScript类内部移除事件监听器?拖拽停止功能异常排查
问题解决:拖拽元素后无法停止拖拽的修复
问题根源
你代码里的核心问题是:添加事件监听时用了event => this.onMouseMove(event)这种箭头函数,每次调用都会生成新的函数引用;而移除监听时用的是this.onMouseMove原方法,两者引用不一致,导致removeEventListener无法找到对应的监听函数,自然无法停止拖拽。另外还有个小问题:设置元素位置时,event.clientX/clientY是数值,需要加上px单位才能生效。
修复后的代码
JavaScript 部分
class Example { rect; // 保存绑定好this的事件处理函数引用 boundMouseMove; boundMouseUp; constructor(rect) { this.rect = rect; // 提前绑定this并保存引用 this.boundMouseMove = this.onMouseMove.bind(this); this.boundMouseUp = this.onMouseUp.bind(this); this.rect.addEventListener('mousedown', this.onMouseDown.bind(this)); } onMouseDown(event) { // 使用保存好的绑定函数添加监听 document.addEventListener('mousemove', this.boundMouseMove); document.addEventListener('mouseup', this.boundMouseUp); } onMouseMove(event) { // 加上px单位 this.rect.style.left = `${event.clientX}px`; this.rect.style.top = `${event.clientY}px`; } onMouseUp(event) { // 用同一个引用移除监听 document.removeEventListener('mousemove', this.boundMouseMove); document.removeEventListener('mouseup', this.boundMouseUp); } } document.addEventListener("DOMContentLoaded", function() { var rect = document.getElementById('rect'); var ex = new Example(rect); });
CSS 部分
#rect { position: absolute; border: 1px solid #ccc; background-color: #DFD; width: 100px; height: 100px; }
HTML 部分
<html> <head> <meta charset="utf-8"/> <title>Test</title> </head> <body> <div id="rect"></div> </body> </html>
关键说明
- 保存函数引用:通过
bind(this)绑定方法的this指向实例,并把绑定后的函数存在实例属性里,确保添加和移除监听时用的是同一个函数引用。 - this绑定:类的方法默认不会绑定实例,所以需要用
bind或者箭头函数来确保onMouseMove和onMouseUp里的this指向当前Example实例。 - 单位问题:设置CSS的left/top属性时,必须带上单位(比如px),否则浏览器无法识别数值。
内容的提问来源于stack exchange,提问作者anvalon
相关产品推荐
相关产品推荐

