如何用EventListener实现拖拽滚动?解决mouseup后mousemove持续触发问题
拖拽日历滚动的事件监听问题修复
问题根源
你遇到的mousemove事件无法移除的核心原因是:绑定事件时用了匿名函数,移除时又创建了新的匿名函数,两个函数引用不相等,导致removeEventListener找不到要移除的事件处理函数,所以松开鼠标后mousemove还会持续触发。
修复方案
直接绑定方法引用,不用匿名函数包裹,确保绑定和移除用同一个函数实例;同时完善拖拽时的初始位置记录逻辑,让滚动计算更准确:
mounted() { this.initScrollCalendar() }, methods: { initScrollCalendar() { const calendar = this.$refs.calendar calendar.scrollLeft = this.position.left; // 直接绑定方法引用,不用匿名函数 calendar.addEventListener('mousedown', this.mouseDownHandler) }, mouseDownHandler(e) { const calendar = this.$refs.calendar // 记录拖拽初始位置 this.dragStart = { x: e.clientX, scrollLeft: calendar.scrollLeft } // 直接绑定方法引用 calendar.addEventListener('mousemove', this.mouseMoveHandler) calendar.addEventListener('mouseup', this.mouseUpHandler) // 阻止默认行为,避免选中文字等干扰 e.preventDefault() }, mouseMoveHandler(e) { const calendar = this.$refs.calendar // 计算拖拽偏移量,更新滚动位置 const dx = e.clientX - this.dragStart.x calendar.scrollLeft = this.dragStart.scrollLeft - dx }, mouseUpHandler() { const calendar = this.$refs.calendar // 用同一个方法引用移除事件 calendar.removeEventListener('mousemove', this.mouseMoveHandler) calendar.removeEventListener('mouseup', this.mouseUpHandler) // 更新position保存最终滚动位置 this.position.left = calendar.scrollLeft } }
关键修改说明
- 所有事件绑定/移除都直接使用
this.方法名,确保引用一致,解决removeEventListener无效的问题 - 在
mousedown时记录初始的鼠标位置和滚动位置,让拖拽滚动的计算逻辑更准确 - 添加
e.preventDefault()阻止默认行为,避免拖拽时选中日历内的文字,影响交互体验 - 在
mouseup时更新position.left保存最终滚动位置,下次初始化时能恢复状态
内容的提问来源于stack exchange,提问作者Philippe
相关产品推荐
相关产品推荐

