Tijmen
Tijmen

Reputation: 35

Vertically scrollable and horizontally draggable divs on mobile

I'm trying to make a mobile website with a card interface. The interaction I want to create is a list of cards I can scroll through and dismiss by swiping them away. In order to achieve this I am currently using jQuery UI with jQuery UI Touch Punch to make it work with touch devices.

The problem I'm running into is that when I scroll with the touch event starting on the div it only uses it for dragging it horizontally, ignoring the vertical swipe. Is there a way to prevent this, or would a different library be better suited for my needs?

This is the website I need it for:

http://tijmen.kervers.nl/B1.2

(it only shows this behaviour on a touch device, works pretty much fine on desktops)

A similar question has been asked before, but remained unanswered:

JQuery-UI horizontal dragging with vertical scrolling

And a less important question; the dragging is pretty jerky what could be causing this? I'm using several libraries and css frameworks on top of each other, my guess is that something is colliding with jQuery UI. I'll be looking into that after the scrolling is fixed, but if someone knows what could be causing it that would be great!

EDIT2:

Nope, that wasn't it. It was "transition: all .2s;" that was messing with the movement.

EDIT1: Looks it's being caused by the dynamic width of the divs I'm draggin around:

jQuery UI make the effect less abrupt and jerky

Upvotes: 0

Views: 1622

Answers (2)

Elliot B.
Elliot B.

Reputation: 17661

I had a problem almost identical to yours and came up with a relatively simple workaround.

Measure any change in the cursor's vertical position and use window.scrollBy to manually scroll the window by the same amount:

var firstY = null;      
var lastY = null;
var currentY = null;
var vertScroll = false;
var initAdjustment = 0;

// record the initial position of the cursor on start of the touch
jqDraggableItem.on("touchstart", function(event) {
    lastY = currentY = firstY = event.originalEvent.touches[0].pageY;
});

// fires whenever the cursor moves
jqDraggableItem.on("touchmove", function(event) {
    currentY = event.originalEvent.touches[0].pageY;
    var adjustment = lastY-currentY;

    // Mimic native vertical scrolling where scrolling only starts after the
    // cursor has moved up or down from its original position by ~30 pixels.
    if (vertScroll == false && Math.abs(currentY-firstY) > 30) {
        vertScroll = true;
        initAdjustment = currentY-firstY;
    }

    // only apply the adjustment if the user has met the threshold for vertical scrolling
    if (vertScroll == true) {
        window.scrollBy(0,adjustment + initAdjustment);
        lastY = currentY + adjustment;
    }

});

// when the user lifts their finger, they will again need to meet the 
// threshold before vertical scrolling starts.
jqDraggableItem.on("touchend", function(event) {
    vertScroll = false;
});

This will closely mimic native scrolling on a touch device.

Upvotes: 1

Tijmen
Tijmen

Reputation: 35

After more searching I have come to the conclusion that this is currently not possible. I suppose a jQuery plugin could be written to solve this, but that is way beyond my skill level.

Upvotes: 0

Related Questions