You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:05:24