jQuery touchSwipe event on element prevents scroll

2020-03-31 03:29发布

问题:

I have some list of div elements ordered vertically. Using jQuery TouchSwipe plugin added swipe event to catch left-right swipe. Idea was to remove element from list by swiping it left or right side like this:

Finally I got something like this:

$(function() {

  $('.swElement').swipe({
      swipeStatus: function(event, phase, direction, distance, duration, fingerCount) {
        console.log(distance);
        if (phase == "move") {
          if (direction == "right") {
            $(this).css({
              'right' : (distance*-1)+'px'
            });  
          }
        } else if (phase == "cancel") {
          $(this).css({
              'right' : 0
          });
        } else if (phase == "end") {
          $(this).animate({
              'right' : '-100%'
          }, 200, function() {
             $(this).remove();
          });
        } else {
           //?????
        }
      },
      threshold: 150,
      maxTimeThreshold: 5000,
	  fingers: 'all'
  });
  
});
.swElement {
  display: block;
  width: 100%;
  height: 50px;
  border: 1px solid black;
  box-sizing: border-box;
  padding: 0 10px;
  line-height: 50px;
  cursor: pointer;
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://dl.dropboxusercontent.com/u/2130702/cdn/jquery.touchSwipe.min.js"></script>

<h2>Swipe right to remove element</h2>

<div class="swElement">Element</div>
<div class="swElement">Element</div>
<div class="swElement">Element</div>
<div class="swElement">Element</div>
<div class="swElement">Element</div>

Problem

It's working great on mobile chrome browser, but prevents up/down scroll on native android browser.

I understand that this swipeStatus catch both left/right and up/dmown directions, but don't know how to prevent is from it - I need only right swipe event.

Any ideas? Thanks in advance.

Update

I can't use jQuery mobile framework, because it conflict's with other scripts which I have to use. Maybe there will be another way to figure out?

回答1:

This is not answering the actual problem for your question, but is an alternative to touch plugging(s). You can still use them for other things in the same app or website.

Coincidence the other day i was having a look at this (jquery-mobile-swipe-list) https://github.com/ksloan/jquery-mobile-swipe-list/blob/master/index.html and this demo http://jsbin.com/luzunu/1/edit?html,css,js,output which uses some Math to detect horizontal touch.

I Created two demos. One that reveals whats behind the elements like the picture in your question and another to drag/swipe to delete like in the code you have.

Any problems with elements flickering using -webkit-transform: translateZ(0); transform: translateZ(0); fixes the flickers.

Demo drag/swipe to reveal behind. i put in a delay of 5 seconds for the touch events to start.

https://jsfiddle.net/4gk27ru1/

Code

    var startPos;
    var handlingTouch = false;
    var itemis;
    setTimeout(function() {

    document.addEventListener('touchstart', function(e) {
      // Is this the first finger going down? 

      if (e.touches.length == e.changedTouches.length) {
        startPos = {
          x: e.touches[0].clientX,
          y: e.touches[0].clientY
        };
      }
    });

    document.addEventListener('touchmove', function(e) {
      // If this is the first movement event in a sequence:
      if (startPos) {
        // Is the axis of movement horizontal?
        if (Math.abs(e.changedTouches[0].clientX - startPos.x) > Math.abs(e.changedTouches[0].clientY - startPos.y)) {
          handlingTouch = true;
          e.preventDefault();
          onSwipeStart(e);
        }
        startPos = undefined;
      } else if (handlingTouch) {
        e.preventDefault();
        onSwipeMove(e);
      }
    });

    document.addEventListener('touchend', function(e) {
      if (handlingTouch && e.touches.length == 0) {
        e.preventDefault();
        onSwipeEnd(e);
        handlingTouch = false;
      }
    });



    function slide(x) {

// slide the element

    $(itemis).css({transform: "translatex("+x+"px)"})
    }

    var swipeOrigin, x, itempos;
    function onSwipeStart(e) {

// find what element is been touched. In your case it may be closest("swElement") but you need to test

      itemis = $(e.target).closest("li").find(".move")

      swipeOrigin = e.touches[0].clientX;
    }
    function onSwipeMove(e) {
      x = e.touches[0].clientX - swipeOrigin;
      slide(x);
    }
    function onSwipeEnd(e) {

    //On Touch End if x (distance traveled to the right) is greater than +35 pixels then slide element  +100 pixels.

      if (x > 35) { 
    slide(100);
      }
      else {
      slide(0);
    }
    }
    }, 5000);

Because the movement of pixels are either in plus or minus to prevent the movement of the elements from either side its easy when using an if statement. Other conditions can be applied using if/else if

Example

move the element from left to right (---->) if plus pixels touched. The Opposite way right to left (<-----) is less than 1 pixel i.e (x < 1)

if (x > 1) { 
 slide(x);
  }

https://jsfiddle.net/v5Ldovmj/

Demo 2 Slide to Delete

https://jsfiddle.net/afkdtjh9/

Additions

// detect window width to fly out the items from whatever the devices window  width is. 

var itemwidth = $(window).width();

// slide item to windows width wait half a second, slide it up and remove from the DOM

slide(itemwidth);
setTimeout(function() {
$(itemis).slideUp("fast").remove()
}, 500);

You can use jquery animate or a pluging like velocity js to control the speed of the elements moving so its smoother as using css transform by itself feels very fast



回答2:

Its simpler than all the answers above. Just add this parameter and you'll be good to go :

    allowPageScroll:"vertical"


回答3:

if (direction == "left"){
   return false;
}

Prevents any events when swiping to the left