How to implement swipe gestures for mobile devices?

后端 未结 9 1064
野性不改
野性不改 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:29

    I like your solution and implemented it on my site - however, with some little improvements. Just wanted to share my code:

    function detectSwipe(id, f) {
        var detect = {
            startX: 0,
            startY: 0,
            endX: 0,
            endY: 0,
            minX: 30,   // min X swipe for horizontal swipe
            maxX: 30,   // max X difference for vertical swipe
            minY: 50,   // min Y swipe for vertial swipe
            maxY: 60    // max Y difference for horizontal swipe
        },
            direction = null,
            element = document.getElementById(id);
    
        element.addEventListener('touchstart', function (event) {
            var touch = event.touches[0];
            detect.startX = touch.screenX;
            detect.startY = touch.screenY;
        });
    
        element.addEventListener('touchmove', function (event) {
            event.preventDefault();
            var touch = event.touches[0];
            detect.endX = touch.screenX;
            detect.endY = touch.screenY;
        });
    
        element.addEventListener('touchend', function (event) {
            if (
                // Horizontal move.
                (Math.abs(detect.endX - detect.startX) > detect.minX)
                    && (Math.abs(detect.endY - detect.startY) < detect.maxY)
            ) {
                direction = (detect.endX > detect.startX) ? 'right' : 'left';
            } else if (
                // Vertical move.
                (Math.abs(detect.endY - detect.startY) > detect.minY)
                    && (Math.abs(detect.endX - detect.startX) < detect.maxX)
            ) {
                direction = (detect.endY > detect.startY) ? 'down' : 'up';
            }
    
            if ((direction !== null) && (typeof f === 'function')) {
                f(element, direction);
            }
        });
    }
    

    Use it like:

    detectSwipe('an_element_id', myfunction);
    

    Or

    detectSwipe('another_element_id', my_other_function);
    

    If a swipe is detected the function myfunction is called with parameter element-id and 'left', 'right', 'up' oder 'down'.

    0 讨论(0)
  • 2020-12-12 15:34

    The simplest solution I've found that doesn't require a plugin:

    document.addEventListener('touchstart', handleTouchStart, false);        
    document.addEventListener('touchmove', handleTouchMove, false);
    var xDown = null;                                                        
    var yDown = null;  
    
    function handleTouchStart(evt) {                                         
        xDown = evt.touches[0].clientX;                                      
        yDown = evt.touches[0].clientY;                                      
    }; 
    
    function handleTouchMove(evt) {
        if ( ! xDown || ! yDown ) {
            return;
        }
        var xUp = evt.touches[0].clientX;                                    
        var yUp = evt.touches[0].clientY;
        var xDiff = xDown - xUp;
        var yDiff = yDown - yUp;
    
        if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
            if ( xDiff > 0 ) {
            /* left swipe */ 
            } else {
            /* right swipe */
            }                       
        } else {
            if ( yDiff > 0 ) {
            /* up swipe */ 
            } else { 
            /* down swipe */
            }                                                                 
        }
        /* reset values */
        xDown = null;
        yDown = null;                                             
    };
    
    0 讨论(0)
  • 2020-12-12 15:42

    There is also an AngularJS module called angular-gestures which is based on hammer.js: https://github.com/wzr1337/angular-gestures

    0 讨论(0)
  • 2020-12-12 15:42

    I looked at several solutions but all failed with scroll and select text being the biggest confusion. Instead of scrolling right I was closing boxes and such.

    I just finished my implementation that does it all for me.

    https://github.com/webdevelopers-eu/jquery-dna-gestures

    It is MIT so do what you want - and yes, it is really simple - 800 bytes minified. You can check it out on my (under-development) site https://cyrex.tech - swiperight on touch-devices should dismiss popup windows.

    0 讨论(0)
  • 2020-12-12 15:45

    Have you tried Hammerjs? It supports swipe gestures by using the velocity of the touch. http://eightmedia.github.com/hammer.js/

    0 讨论(0)
  • 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%;
    }
    <div id='swipeme'>
      swipe me
    </div>

    0 讨论(0)
提交回复
热议问题