移动端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

猜你喜欢

转载自blog.csdn.net/qq_41887214/article/details/124706132