prevent touchstart when swiping

前端 未结 11 2041
萌比男神i
萌比男神i 2020-11-30 20:09

I have a scrollable list on a mobile device. They want people to be able to scroll the list via swiping, and also select a row by tapping.

The catch is combining th

相关标签:
11条回答
  • 2020-11-30 21:05
    var touchmoved;
    $('button').on('touchend', function(e){
        if(touchmoved != true){
            // button click action
        }
    }).on('touchmove', function(e){
        touchmoved = true;
    }).on('touchstart', function(){
        touchmoved = false;
    });
    
    0 讨论(0)
  • 2020-11-30 21:05

    if you want to do this for multiple elements and also need mouse and pointer events:

    var elems = $('YOURMULTISELECTOR'); // selector for multiple elements
    elems.unbind('mousdown pointerdown touchstart touchmove mouseup pointerup touchend');
    var elem = null;
    elems.on('mousdown pointerdown touchstart', function (e) {
        elem = yourSingleSelector(e);
    }).on('touchmove', function (e) {
        elem = null;                
    }).on('mouseup pointerup touchend', function (e) { 
        if (elem == yourSingleSelector(e)) {                    
            // do something
        }
    });
    
    0 讨论(0)
  • 2020-11-30 21:08

    Quoting from DA.:

    This is a working example:

    var touch_pos;
    $(document).on('touchstart', '.action-feature', function(e) {
      e.preventDefault();
      touch_pos = $(window).scrollTop();
    }).on('click touchend', '.action-feature', function(e) {
      e.preventDefault();
      if(e.type=='touchend' && (Math.abs(touch_pos-$(window).scrollTop())>3)) return;
      alert("only accessed when it's a click or not a swipe");
    });
    
    0 讨论(0)
  • 2020-11-30 21:09

    What you basically want to do is to detect what is a swipe and what is a click.

    We may set some conditions:

    1. Swipe is when you touch at point p1, then move your finger to point p2 while still having the finger on the screen, then releaseing.
    2. A click is when you tap start tapping and end tapping on the same element.

    So, if you store the coordinates of where your touchStart occured, you can measure the difference at touchEnd. If the change is large enough, consider it a swipe, otherwise, consider it a click.

    Also, if you want to do it really neat, you can also detect which element you are "hovering" over with your finger during a touchMove, and if you're not still at the element on which you started the click, you can run a clickCancel method which removes highlights etc.

    // grab an element which you can click just as an example
    var clickable = document.getElementById("clickableItem"),
    // set up some variables that we need for later
    currentElement,
    clickedElement;
    
    // set up touchStart event handler
    var onTouchStart = function(e) {
        // store which element we're currently clicking on
        clickedElement = this;
        // listen to when the user moves finger
        this.addEventListener("touchMove" onTouchMove);
        // add listener to when touch end occurs
        this.addEventListener("touchEnd", onTouchEnd);
    };
    // when the user swipes, update element positions to swipe
    var onTouchMove = function(e) {
        // ... do your scrolling here
    
        // store current element
        currentElement = document.elementFromPoint(x, y);
        // if the current element is no longer the same as we clicked from the beginning, remove highlight
        if(clickedElement !== currentElement) {
            removeHighlight(clickedElement);
        }
    };
    // this is what is executed when the user stops the movement
    var onTouchEnd = function(e) {
        if(clickedElement === currentElement) {
            removeHighlight(clickedElement);
            // .... execute click action
        }
    
        // clean up event listeners
        this.removeEventListener("touchMove" onTouchMove);
        this.removeEventListener("touchEnd", onTouchEnd);
    };
    function addHighlight(element) {
        element.className = "highlighted";
    }
    function removeHighlight(element) {
        element.className = "";
    }
    clickable.addEventListener("touchStart", onTouchStart);
    

    Then, you will have to add listeners to you scrollable element also, but there you won't have to worry about what happens if the finger has moved inbetween touchStart and touchEnd.

    var scrollable = document.getElementById("scrollableItem");
    
    // set up touchStart event handler
    var onTouchStartScrollable = function(e) {
        // listen to when the user moves finger
        this.addEventListener("touchMove" onTouchMoveScrollable);
        // add listener to when touch end occurs
        this.addEventListener("touchEnd", onTouchEndScrollable);
    };
    // when the user swipes, update element positions to swipe
    var onTouchMoveScrollable = function(e) {
        // ... do your scrolling here
    };
    // this is what is executed when the user stops the movement
    var onTouchEndScrollable = function(e) {
        // clean up event listeners
        this.removeEventListener("touchMove" onTouchMoveScrollable);
        this.removeEventListener("touchEnd", onTouchEndScrollable);
    };
    scrollable.addEventListener("touchStart", onTouchStartScrollable);
    

    // Simon A.

    0 讨论(0)
  • 2020-11-30 21:09

    Here's what I eventually came up with to allow for a list of items to be scrollable via swipe, but also each item to be 'triggerable' via a tap. In addition, you can still use with a keyboard (using onclick).

    I think this is similar to Netlight_Digital_Media's answer. I need to study that one a bit more.

    $(document)
    // log the position of the touchstart interaction
    .bind('touchstart', function(e){ 
      touchStartPos = $(window).scrollTop();
    })
    // log the position of the touchend interaction
    .bind('touchend', function(e){
      // calculate how far the page has moved between
      // touchstart and end. 
      var distance = touchStartPos - $(window).scrollTop();
    
      var $clickableItem; // the item I want to be clickable if it's NOT a swipe
    
      // adding this class for devices that
      // will trigger a click event after
      // the touchend event finishes. This 
      // tells the click event that we've 
      // already done things so don't repeat
    
      $clickableItem.addClass("touched");      
    
      if (distance > 20 || distance < -20){
            // the distance was more than 20px
            // so we're assuming they intended
            // to swipe to scroll the list and
            // not selecting a row. 
        } else {
            // we'll assume it was a tap 
            whateverFunctionYouWantToTriggerOnTapOrClick()
        }
    });
    
    
    $($clickableItem).live('click',function(e){
     // for any non-touch device, we need 
     // to still apply a click event
     // but we'll first check to see
     // if there was a previous touch
     // event by checking for the class
     // that was left by the touch event.
    if ($(this).hasClass("touched")){
      // this item's event was already triggered via touch
      // so we won't call the function and reset this for
      // the next touch by removing the class
      $(this).removeClass("touched");
    } else {
      // there wasn't a touch event. We're
      // instead using a mouse or keyboard
      whateverFunctionYouWantToTriggerOnTapOrClick()
    }
    });
    
    0 讨论(0)
提交回复
热议问题