jQuery UI可拖动在移动设备上会阻止滚动

8

我有一些可拖动的元素,它们的宽度占据整个屏幕,并且垂直排列。

为了在移动端上启用jQuery拖动功能,我使用了一个叫做jquery.ui.touch-punch的插件。但是问题在于,这些可拖动元素会阻止用户滚动页面。

$('#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


有没有找到解决这个问题的方法?我也遇到了完全相同的问题。 - whitwhoa
一个解决方案可能是在界面上添加固定在屏幕顶部和/或底部的上下按钮。 - JBS
3个回答

5
我不认为在jquery.ui.touch-punch.js中注释掉event.preventDefault()仍然有效。我尝试了同样的解决方案,发现jQuery UI draggable本身阻止了垂直滚动的默认行为——即使元素只设置在x轴上拖动。
对我有效的解决方案是测量光标垂直位置的任何变化,并使用window.scrollBy手动滚动相同的距离:
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;
});

这将会紧密地模拟触摸设备上的本机滚动。


这是一个很好的解决方案,你认为它能更加流畅吗?我在诺基亚Lumia上测试了一下,垂直滚动不够流畅,有些抖动。 - almost a beginner
是的,它并不完美,但使用JavaScript修复可能已经尽可能好了。我没有在诺基亚Lumia上进行测试,但我已经在S7、iPhone 6和iPod Touch(第六代)上进行了测试——这些设备上的抖动很少,除非你特意寻找,否则几乎不会注意到。这些手机都有基于Webkit的浏览器。Lumia是Windows手机,对吗?您可以尝试使用本地平滑滚动(请参见https://blog.hospodarets.com/native_smooth_scrolling)。然而,并不是所有移动浏览器都支持它,而且我并没有真正注意到启用与禁用之间的区别。 - Elliot B.
我发现jQuery UI的新版本存在一个问题,它们将可拖动元素的CSS设置为touch-action: none,从而阻止了默认操作。尝试将其更改为auto,这是默认设置。 - Tim Tisdall

3

我在 Scrolling jQuery UI touch punch 找到了解决方案。你需要在 jquery.ui.touch-punch.js 的第38行中删除event.preventDefault()。目前我只在索尼Xperia Z1 Compact,Android 5,Chrome上进行了测试,但在一个与这里命名的项目非常相似的项目中非常有效。


唯一的问题是,在移除该行后,水平滚动不太流畅。(诺基亚Lumia) - almost a beginner
这在我的三星S8+上确实可以工作,但我正在使用拖放功能,所以当我尝试移动项目时,列表会滚动...!!! - Mikeys4u

1
我遇到了这样的问题:当我的div元素可拖动时,我无法在移动设备上滚动页面。原因是Jquery UI的CSS代码将以下代码设置为none。通过将其还原为initial,一切都恢复正常了!
.ui-draggable-handle {-ms-touch-action:initial!important;touch-action:initial!important}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接