How to implement swipe gestures for mobile devices?

后端 未结 9 1134
野性不改
野性不改 2020-12-12 14:58

I have an application made in AngularJS which has arrow key navigation to switch views.

I want to implement this navigation using swipe for touch devices. I tried jG

9条回答
  •  盖世英雄少女心
    2020-12-12 15:46

    NOTE: Greatly inspired by EscapeNetscape's answer, I've made an edit of his script using modern javascript in a comment. I made an answer of this due to user interest and a massive 4h jsfiddle.net downtime. I chose not to edit the original answer since it would change everything...


    Here is a detectSwipe function, working pretty well (used on one of my websites). I'd suggest you read it before you use it. Feel free to review it/edit the answer.

    // usage example
    detectSwipe('swipeme', (el, dir) => alert(`you swiped on element with id ${el.id} to ${dir} direction`))
    
    // source code
    
    // Tune deltaMin according to your needs. Near 0 it will almost
    // always trigger, with a big value it can never trigger.
    function detectSwipe(id, func, deltaMin = 90) {
      const swipe_det = {
        sX: 0,
        sY: 0,
        eX: 0,
        eY: 0
      }
      // Directions enumeration
      const directions = Object.freeze({
        UP: 'up',
        DOWN: 'down',
        RIGHT: 'right',
        LEFT: 'left'
      })
      let direction = null
      const el = document.getElementById(id)
      el.addEventListener('touchstart', function(e) {
        const t = e.touches[0]
        swipe_det.sX = t.screenX
        swipe_det.sY = t.screenY
      }, false)
      el.addEventListener('touchmove', function(e) {
        // Prevent default will stop user from scrolling, use with care
        // e.preventDefault();
        const t = e.touches[0]
        swipe_det.eX = t.screenX
        swipe_det.eY = t.screenY
      }, false)
      el.addEventListener('touchend', function(e) {
        const deltaX = swipe_det.eX - swipe_det.sX
        const deltaY = swipe_det.eY - swipe_det.sY
        // Min swipe distance, you could use absolute value rather
        // than square. It just felt better for personnal use
        if (deltaX ** 2 + deltaY ** 2 < deltaMin ** 2) return
        // horizontal
        if (deltaY === 0 || Math.abs(deltaX / deltaY) > 1)
          direction = deltaX > 0 ? directions.RIGHT : directions.LEFT
        else // vertical
          direction = deltaY > 0 ? directions.UP : directions.DOWN
    
        if (direction && typeof func === 'function') func(el, direction)
    
        direction = null
      }, false)
    }
    #swipeme {
      width: 100%;
      height: 100%;
      background-color: orange;
      color: black;
      text-align: center;
      padding-top: 20%;
      padding-bottom: 20%;
    }
    swipe me

提交回复
热议问题