jQuery UI可排序--页面可滚动时div不可拖动

7
提前感谢您查看我的问题。
我正在创建一个网站,其中有一系列DIV可以使用jQuery UIs sortable在Y轴上排序。由于我希望它在使用触摸的移动设备上运行,因此我不得不添加一个小技巧来确保jQuery UI可用(因为它目前不支持触摸事件)。这个技巧叫做jQuery UI touch punch。网站:jQuery UI touch punch。GitHub:jQuery UI touch punch
现在出现了我的问题。有时列表会变得非常大,以至于网站将变得可滚动,当网站可滚动时,我无法正确地拖动项目,因为当我尝试拖动DIV时,它只是滚动页面。唯一能够拖动它的方法是双击该项目,然后再拖动它。但这真的不是我想要的,因为它非常繁琐和不自然。
现在的问题是,是否有一种方法可以在尝试拖动可拖动集合中的一个项目时禁用滚动。我尝试添加overflow-y: hidden或添加touch-action : none。不幸的是,这似乎没有起作用。

摘要
我拥有:使用jQuery UI和jquery UI touch punch,我可以使用触摸设备拖动和排序一组Div的列表。
问题:列表会变得很大,因此网站可以滚动,这会禁用单击拖动,需要双击才能拖动项目。
我想要的:即使有滚动条,我也希望能够拖动项目(无需双击)。

我该如何实现这样的行为/从哪里开始?欢迎提供任何提示和解决方案。


最后,这是我的FIDDLE

编辑:

我正在使用:
IE 11
jQuery版本1.11.1
jQuery-ui版本1.11.4


也许与“包含性”有关,例如 containment: "window"。这是你所询问的内容吗? - Twisty
@Twisty,不幸的是,这并没有起作用。 - TheWandererr
你看过这个吗?https://dev59.com/sVsX5IYBdhLWcg3wRdp_ - Serg Chernata
你肯定不是在说你想完全禁用滚动吧?那么用户该如何访问屏幕底部的内容呢? - David Knipe
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Bharatsing Parmar
2个回答

8

尝试将touch punch库(建议)替换为以下JS片段(或与其同时使用),并在$(document).ready();上调用init()函数:

  • 请注意,您可以对#wrapper的样式进行注释,这些样式仅用于溢出测试。
  • 理想情况下,您应该在可拖动项中留出一些空间,以便滚动而不会发生不需要的拖拽。

以下是片段:

$(document).ready(function() {
    init();
    $("#myContainer").sortable({
        //your code
    })
});

function touchHandler(event) {
    var touch = event.changedTouches[0];

    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent({
            touchstart: "mousedown",
            touchmove: "mousemove",
            touchend: "mouseup"
        }[event.type], true, true, window, 1,
        touch.screenX, touch.screenY,
        touch.clientX, touch.clientY, false,
        false, false, false, 0, null);

    touch.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() {
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);
}

--->替换touch punch的片段Fiddle<---

--->带有touch punch的片段Fiddle<---

(两者在移动版Safari和Chrome中都经过测试,在第一次轻触时完成拖动操作)


嘿,感谢您的解决方案,很抱歉回复晚了。它似乎在Chrome中可以工作,但是当我触摸屏幕时出现以下错误:Uncaught TypeError: Failed to execute 'initMouseEvent' on 'MouseEvent': parameter 4 is not of type Window - TheWandererr
在我必须使用的Internet Explorer 11中没有出现错误,但您的解决方案却无法工作。不幸的是我没有在我的问题中提到这一点。有什么办法可以让它在Internet Explorer中工作吗?似乎滚动条具有更高的优先级或其他什么问题。如果没有其他答案提供,我还是会给你悬赏的。 - TheWandererr
非常感谢。这个解决方案对我有效。有一个更新——我不得不从TouchHandler中删除preventDefault,因为它会在清除画布等方面造成其他复杂性。 - Neerav Patel

1

尝试将这些行添加到您的touch punch库js文件中。

function simulateMouseEvent(event, simulatedType) {   
// Ignore multi-touch events


> if (event.originalEvent.touches.length > 1) {
>         return;
>     }
> 
>     var touch = event.originalEvent.changedTouches[0],
>         simulatedEvent = document.createEvent('MouseEvents');
> 
>     if ($(touch.target).is("select")) {
>         event.stopPropagation();
>     } else {
>         event.preventDefault();
>     }
`

包括上述行。

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