Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI draggable prevents scrolling on mobile

I have draggable elements with full screen width listed vertically.

I am using a plugin called (jquery.ui.touch-punch) to enable jQuery draggable on mobile. But the problem is that the draggable elements prevent the user from scrolling the page.

$('#novieList .element .content').draggable({
    axis: 'x',
    revert: function() {
        return $(this).position().left < 30;
    },
    containment: [ 0, 0, 75, 0 ],
    scope: 'element',
    scroll: false,
    delay: 300,
    drag: function(event, ui) {
        return true;
    },
    start: function(event, ui) {
        // Prevent to drag the element after open it
        var left = $(this).position().left;
        return left == 0;
    },
    stop: function(event, ui) {
        var left = $(this).position().left;
        if (left != 0) {
            $(this).offset({left: 75});
        }
        return true;
    }
});

enter image description here

like image 436
faressoft Avatar asked Feb 07 '15 00:02

faressoft


3 Answers

I don't believe commenting out event.preventDefault() in jquery.ui.touch-punch.js works any longer. I tried the same solution and found that jQuery UI draggable itself was blocking the default behavior of a vertical scroll -- even when the element is set to drag only along the x-axis.

The solution that worked for me was to 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.

like image 163
Elliot B. Avatar answered Oct 29 '22 06:10

Elliot B.


I found a solution to that problem at Scrolling jQuery UI touch punch. You have to remove a event.preventDefault() in jquery.ui.touch-punch.js on line 38. So far I have only tested on Sony Xperia Z1 Compact, Android 5, Chrome, but it works very well in a project very similar to one named here.

like image 22
psyinfinity Avatar answered Oct 29 '22 06:10

psyinfinity


I had the problem regarding that I could scroll on mobile when my div was dragable, as the CSS of the Jquery UI had the following code set to none, so by reverting the changes by putting them on initial everything worked again!

.ui-draggable-handle {-ms-touch-action:initial!important;touch-action:initial!important}

like image 41
Rafaël De Jongh Avatar answered Oct 29 '22 07:10

Rafaël De Jongh