自定义手势判断在日历上的应用

自定义手势判断在日历上的应用

在移动端,通常日历展示为当前月的日期纪录,当切换月份的过程中,需要通过手势左滑或者右滑进行月份切换,以下说明如何自行完成一个滑动的手势判断以及逻辑处理

这里借助Vue的自定义指令进行代码阐述,SELECTWRAP_DOM为绑定的DOM元素

bind(el, binding, vnode) {
        var startX = 0
        var startY = 0
        var endX = 0
        var endY = 0
        const SELECTWRAP_DOM = el
        var judgeX = 0
        var judgeY = 0
        var lockY = false
        SELECTWRAP_DOM.addEventListener('touchstart', (event) => {
            // 监听滑动开始,细节见下方
        }
        SELECTWRAP_DOM.addEventListener('touchmove', (event) => {
            // 监听滑动,细节见下方
        }
        SELECTWRAP_DOM.addEventListener('touchend', (event) => {
            // 监听滑动结束,细节见下方
        }
}
  • 首先获取到dom元素之后,对其绑定touchstart事件,也就作为手势判断的起点
  SELECTWRAP_DOM.addEventListener('touchstart', (event) => {
      var touch = event.touches[0]
      // 获取当前触控点起点的坐标,包含X,Y
      startX = touch.pageX
      startY = touch.pageY
  })
  • 然后对dom监听touchmove事件,但是此事件只获取起始的第一个点,作为手势判断的终点
  SELECTWRAP_DOM.addEventListener('touchmove', (event) => {
      var touch = event.targetTouches[0]
      // 手势滑动时,手势坐标不断变化,取最后一点 的坐标为最终的终点坐标
      endX = touch.pageX
      endY = touch.pageY
      // 这里纪录拖动之后的第一个点,在拖动过程中只纪录一次
      if (judgeX == 0 && judgeY == 0) {
          judgeX = endX
          judgeY = endY
      }
      let Ylength = Math.abs(judgeY - startY)
      let Xlength = Math.abs(judgeX - startX)
      // 根据等边三角形计算角度关系
      lockY = Ylength / Xlength < 1
      if (lockY) {
          // 屏蔽Y轴滑动
          event.preventDefault()
            // 执行X轴滑动动画
          SELECTWRAP_DOM.style.transform = `translateX(${endX - startX}px)`
      }
      // 如果没有判定为X轴滑动,即不会执行动画,只能上下拖动
  })

在这里插入图片描述

  • 最后监听touchend事件,对判断数据进行重置以及其他处理
  SELECTWRAP_DOM.addEventListener('touchend', (event) => {
      var distanceX = endX - startX
      // 将拖动效果还原,偏移归0
      SELECTWRAP_DOM.style.transform = `translateX(0px)`
      /* 如果当前偏移存在,且偏移量>50,因为小的偏移量可能是用户误操作造成,并且起点和终点的X轴都发生了变化,有可能用户只是点了一下
      那么endX必为0,disctance计算出来就会产生偏移,所以排除此情况,执行自定义指令函数
      */
      // 如果X轴滑动了,执行命令,否则即清空数据,供下次滑动检测
      if (distanceX != 0 && (Math.abs(distanceX) > 50 && lockY) && startX != 0 && endX != 0) binding.value(distanceX)
      // 将缓存的坐标点还原,供下次使用
      startX = 0
      startY = 0
      endX = 0
      endY = 0
      judgeX = 0
      judgeY = 0
      lockY = false
  })

结论:在比值判断之前采取的是固定数值判断,缺点在于不同屏幕下,会存在误判的可能,或者Y轴敏感,或者X轴敏感,体验感都不好。最终采用比值关系之后,效果显著提升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_36851403

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

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

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

打赏作者

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

抵扣说明:

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

余额充值