Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

prevent touchstart when swiping

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 the two. I don't want a row to be selected if you are actually scrolling the list. Here's what I've found:

Doesn't trigger when scrolling:

  • click
  • mouseup

Does trigger when scrolling:

  • mousedown
  • touchstart
  • touchend

The simple solution is to just stick with the click event. But what we're finding is that on certain blackberry devices, there is a VERY noticeable lag between touchstart and it then triggering either click or mouseup. This delay is significant enough to make it unusable on those devices.

So that leaves us with the other options. However, with those options, you can scroll the list without triggering the row you touched to start the scroll.

What is the best practice here to resolve this?

like image 308
DA. Avatar asked Aug 15 '11 19:08

DA.


2 Answers

var touchmoved; $('button').on('touchend', function(e){     if(touchmoved != true){         // button click action     } }).on('touchmove', function(e){     touchmoved = true; }).on('touchstart', function(){     touchmoved = false; }); 
like image 170
Levarne Sobotker Avatar answered Oct 07 '22 06:10

Levarne Sobotker


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.

like image 31
Netlight_Digital_Media Avatar answered Oct 07 '22 08:10

Netlight_Digital_Media