jQuery UI Draggable and Page Scrolling (on mobile)

2019-04-10 17:05发布

I have a page full of draggable items (only in horizontal).

If I open my page on a touch device I can't scroll the page down, obviously because the page is full of draggable elements. How can I make the page scrollable again?

Here's the draggable() code I'm using:

$('li').draggable({
axis: 'x',
drag: function( event, ui ) {
    if(ui.position.left > 0)
        ui.position.left = 0;
    if(ui.position.left < -250)
        ui.position.left = -250;
}
});

2条回答
趁早两清
2楼-- · 2019-04-10 17:42

Just in case someone needs this:

The problem can be solved by using the "handle" option of draggable(). For example, if I have a div with a width of 500px, I can insert another (transparent) div inside it aligned to the right (for example) and with a width of 250px. Then I set this last div as the handle of the draggable div.

查看更多
贪生不怕死
3楼-- · 2019-04-10 17:49

Using a handle is the obvious choice, but in some instances it's not a option.

In my scenario I had an inbox list whose items that you could drag to the left or right to expose action buttons. The entire inbox item must be draggable -- employing a drag handle would be unintuitive.

jQuery's draggable prevents vertical scrolling on touch screens if the touch was initiated inside a draggable element. So if the screen was filled with draggable inbox items, then the user would become trapped -- unable to scroll up or down.

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.

查看更多
登录 后发表回答