移动端JS判断手势方向

使用

new TouchMoveDirection({
  el: document.querySelector('.perfect-moment'),
  onMoveEnd: (result) => {
    if (result.direction === 'to-bottom') {
      // do something
    }
  }
})

代码

// 手势
class TouchMoveDirection {
  constructor({ el, onMoveEnd, needTouchPosition }) {
    this.onMoveEnd = onMoveEnd
    this.el = el
    this.startX = null // 开始触碰的pageX
    this.startY = null // 开始触碰的pageY
    this.moveEndX = null // 结束触碰的pageX
    this.moveEndY = null // 结束触碰的pageY
    this.X = null // X轴滑动距离
    this.Y = null // Y轴滑动距离
    this.needTouchPosition = needTouchPosition // 是否返回 touchPosition
    this.touchPosition = null // 开始触碰的位置,左上、右上、左下、右下
    this.duration = 0 // 滑动时长,超过该时间不触发滑动,单位毫秒。
    this.startTime = 0 // 开始时间
    this.endTime = 0 // 结束时间

    if (this.needTouchPosition) {
      const boundingClientRect = this.el.getBoundingClientRect()

      // 左上、右上、左下、右下 四个区域的界线坐标
      this.boundaryLine = {
        pageX: (boundingClientRect.left + boundingClientRect.right) / 2,
        pageY: this.el.offsetTop + (boundingClientRect.height / 2)
      }
    }
    this.init()
  }
  init = () => {
    this.el?.addEventListener('touchstart', this.touchstart)

    this.el?.addEventListener('touchend', this.touchend)
  }

  // 开始触碰
  touchstart = (e) => {
    e.stopPropagation()
    this.startTime = new Date().getTime()
    this.startX = e.changedTouches[0].pageX
    this.startY = e.changedTouches[0].pageY

    if (this.needTouchPosition) {
      this.touchPosition = this.getTouchPosition(this.startX, this.startY)
    }
  }

  // 结束触碰
  touchend = (e) => {
    e.stopPropagation()
    this.endTime = new Date().getTime()
    this.duration = this.endTime - this.startTime

    // 滑动时间小于1秒视为有效滑动
    if (this.duration < 1000) {
      this.moveEndX = e.changedTouches[0].pageX
      this.moveEndY = e.changedTouches[0].pageY
      this.X = this.moveEndX - this.startX
      this.Y = this.moveEndY - this.startY

      // 滑动距离大于 30px 视为有效滑动
      if (Math.abs(this.X) > Math.abs(this.Y) && this.X > 0 && Math.abs(this.X) > 30) {
        this.onMoveEnd?.({
          touchPosition: this.touchPosition,
          direction: 'to-right'
        })
      } else if (Math.abs(this.X) > Math.abs(this.Y) && this.X < 0 && Math.abs(this.X) > 30) {
        this.onMoveEnd?.({
          touchPosition: this.touchPosition,
          direction: 'to-left'
        })
      } else if (Math.abs(this.Y) > Math.abs(this.X) && this.Y > 0 && Math.abs(this.Y) > 30) {
        this.onMoveEnd?.({
          touchPosition: this.touchPosition,
          direction: 'to-bottom'
        })
      } else if (Math.abs(this.Y) > Math.abs(this.X) && this.Y < 0 && Math.abs(this.Y) > 30) {
        this.onMoveEnd?.({
          touchPosition: this.touchPosition,
          direction: 'to-top'
        })
      }
    }
  }

  // 获取开始触摸的区域
  getTouchPosition = (startX, startY) =>  {
    // 在右边
    if (startX >= this.boundaryLine.pageX) {
      // 下边
      if (startY >= this.boundaryLine.pageY) {
        return 'right-bottom'
      } else {
        // 上面
        return 'right-top'
      }
    } else {
      // 在左边

      // 下边
      if (startY >= this.boundaryLine.pageY) {
        return 'left-bottom'
      } else {
        // 上面
        return 'left-top'
      }
    }
  }

  off() {
    this.el?.removeEventListener('touchstart', this.touchstart)
    this.el?.removeEventListener('touchend', this.touchend)
  }
}

export default TouchMoveDirection
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__畫戟__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值