简体   繁体   中英

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;
    }
});

在此输入图像描述

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.

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.

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}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM