prevent touchstart when swiping

2019-01-10 06:22发布

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?

12条回答
对你真心纯属浪费
2楼-- · 2019-01-10 06:54

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
    }
});
查看更多
地球回转人心会变
3楼-- · 2019-01-10 06:55

I did this with a bit of a different work around. It's definitely not very elegant and certainly not suited to most situations, but it worked for me.

I have been using jQuery's toggleSlide() to open and close input divs, firing the slide on touchstart. The problem was that when the user wanted to scroll, the touched div would open up. To stop this from happening, (or to reverse it before the user noticed) I added a touchslide event to the document which would close the last touched div.

In more depth, here is a code snippet:

var lastTouched;

document.addEventListener('touchmove',function(){
    lastTouched.hide();
});

$('#button').addEventListener('touchstart',function(){
    $('#slide').slideToggle();
    lastTouched = $('#slide');
});

The global variable stores the last touched div, and if the user swipes, the document.touchmove event hides that div. Sometimes you get a flicker of a div poking out but it works for what I need it to, and is simple enough for me to come up with.

查看更多
Viruses.
4楼-- · 2019-01-10 07:00

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");
});
查看更多
Root(大扎)
5楼-- · 2019-01-10 07:02

I've implemented an easier solution by doing this:

$el.mouseover(function() {
    if (jQuery.browser.mobile) {
        //your javscript function
    }
});
查看更多
我命由我不由天
6楼-- · 2019-01-10 07:06

Some of these solutions worked for me, but in the end I found that this lightweight library was simpler to setup.

Tocca.js: https://github.com/GianlucaGuarini/Tocca.js

It's quite flexible and detects touch as well as swipe, double-tap etc.

查看更多
做自己的国王
7楼-- · 2019-01-10 07:11

I had the same problem, here's a quick solution which works for me

$(document).on('touchstart', 'button', function(evt){ 
    var oldScrollTop = $(window).scrollTop();
    window.setTimeout( function() {
        var newScrollTop = $(window).scrollTop();
        if (Math.abs(oldScrollTop-newScrollTop)<3) $button.addClass('touchactive');
    }, 200);
});

basically instead of handling touchstart immediately, wait for some milliseconds (200ms in this example), then check the scroll position, had scrollposition changed, then we need not to handle touchstart.

查看更多
登录 后发表回答