如何在触屏设备上使jQueryUI的拖放功能正常工作

46

这是一个我希望有人回复告诉我我是个白痴的情况。但我仍然惊讶于jQueryUI拖放在触屏设备上无法使用。我没有测试所有设备,但我在过去的一年里尝试了iphone\ipad\android 2、3&4,没有一个可以用。刚刚在新的Android上尝试了最新版本。仍然没有反应。不信,请在移动设备上访问演示页面并尝试使用拖放示例。什么都没发生。

这里是否存在技术问题或核心不兼容性?修复是否如此简单,以至于不值得写?jQuery开发人员不使用移动设备吗?我曾经在Stack Overflow上看到过一些“解决方案”,但它们都是“hack”,而且我尝试过的所有方法都无效。

我很困惑。有人能给这个问题带来一些光明吗?


1
我认为这更多是目标受众的问题。jQuery UI 最初并不是为处理移动设备而编写的。它甚至无法与 jQuery Mobile 很好地兼容。虽然其中的某些部分仍可在移动设备上良好运行,但任何涉及拖动的内容都将失败。 - Kevin B
4个回答

83

如果你只想让你现有的jQuery UI代码能够与触摸事件一起使用,那么你可以使用jQuery UI Touch Punch猴子补丁。

唯一的“技术问题或核心不兼容性”是jQuery UI (1.x)仅监听鼠标事件,而不是触摸事件(请参见@ScottGonzales的回答以了解历史原因)。上面的jQuery touch punch就解决了这个问题。甚至你可以在该页面上尝试一些jQuery UI示例,它们也能正常工作。通常情况下,使用Touch Punch是目前被接受的解决方案。


1
“_Touch Punch monkey patch_” 声音。 - IvanM
1
不是最好的解决方案:如果要拖动的元素占据整个视口,使用jQuery UI Touch Punch会防止文档滚动。甚至对于你想要在容器中隐藏溢出的仅可水平拖动的元素(如可拖动的旋转木马),这可能会成为一个问题。在这种情况下,旋转木马会阻止用户上下滚动文档。我更喜欢jQuery Touch(github.com/ajlkn/jquery.touch),它使得在移动设备上仅能通过触摸进行拖动(鼠标手势可以被过滤),并且不会阻止触摸事件传播(因此,文档可以被滚动)。 - MaxAuray
2
@MaxAuray,你的评论可以作为这个问题的一个很好的备选答案!请注意,当我最初回答这个问题时,2012年还不存在jquery.touch >_< - forivall
1
我最初发现Touch Punch对我不起作用(由于Chrome 70在桌面上禁用ontouch API)。 我在https://github.com/furf/jquery-ui-touch-punch/issues/309中找到了解决方案。 在我的情况下,将第14行更改为以下内容即可解决问题:$.support.touch =('ontouchstart' in document || 'ontouchstart' in window || navigator.maxTouchPoints> 0 || navigator.msMaxTouchPoints> 0); - Rob Powell
1
@RobPowell 你也可以在 https://useful-forks.github.io/ 找到有用的 touch punch 分支 - 我看到最有前途的是 https://github.com/AndrewDodd42/jquery-ui-touch-punch 。请注意,我很久没有使用过jquery,所以我还没有评估它们。 - forivall

34
jQuery UI不支持触摸设备,这背后有一个很长的历史原因,但归根结底是因为Touch Event是一种非标准的基于WebKit的实现。当时,未来看起来黯淡无光。苹果拥有没人想接近的专利;因此,Mozilla使用了自己的流式触摸事件系统,但从未流行起来。不清楚微软和Opera会怎么做。Paul Bakaus(jQuery UI的创建者)4年前希望实现iPhone支持。我想等待官方标准。

时间过去了,Mozilla放弃了他们的触摸事件,微软实现了自己的指针事件系统。W3C成立了一个工作组来标准化触摸事件并调查苹果的专利。触摸事件工作组已发布建议并解散。微软最终提交了一个建议来标准化指针事件,并且现在有一个W3C指针事件工作组。

我们目前正在进行一个针对所有jQuery UI交互的设备无关重写,它将成为jQuery UI 2.0的一部分。在那之前,您可以使用jQuery UI Touch Punch
今年早些时候,我写了一些关于Touch Events历史以及Pointer Events为什么提供更好未来的文章。您可以在jQuery博客上阅读相关内容。

不是最好的解决方案:如果要拖动的元素占据整个视口,使用jQuery UI Touch Punch会防止文档滚动。甚至对于你想要在容器中隐藏溢出的仅可水平拖动的元素(如可拖动的旋转木马),这可能会成为一个问题。在这种情况下,旋转木马会阻止用户上下滚动文档。我更喜欢jQuery Touch(github.com/ajlkn/jquery.touch),它使得在移动设备上仅能通过触摸进行拖动(鼠标手势可以被过滤),并且不会阻止触摸事件传播(因此,文档可以被滚动)。 - MaxAuray

1

使用jQuery UI Touch Punch似乎是最好的方法。

<script src="../jquery-ui-1.13.0/external/jquery/jquery.js"></script>
<script src="../jquery-ui-1.13.0.custom/jquery-ui.min.js"></script>
<script src="../jquery-ui-1.13.0/jquery-ui.min.js"></script>
<script src="../jquery-ui-touch-punch/jquery.ui.touch-punch.min.js"></script>

<link href="../bootstrap-5.1.1/css/bootstrap.min.css" rel="stylesheet" />

<script>
    $(function () {
        $("#sortable").sortable();
    });
</script>

<div class="container">
    <div class="row">
        <div class="col-md-12">
            <ul id="sortable" class="list-group">
                <li class="list-group-item active">Item 1</li>
                <li class="list-group-item">Item 2</li>
                <li class="list-group-item">Item 3</li>
                <li class="list-group-item">Item 4</li>
                <li class="list-group-item">Item 5</li>
                <li class="list-group-item">Item 6</li>
                <li class="list-group-item">Item 7</li>
                <li class="list-group-item">Item 8</li>
            </ul>
        </div>
    </div>
</div>

https://jsfiddle.net/igorkrupitsky/cw5n0xku/1/


0

看看jQTouch

它是一个jQuery插件,有助于弥合桌面和触摸设备之间的事件差距。


似乎已经停止更新,请查看jQuery Touch(github.com/ajlkn/jquery.touch)。 - MaxAuray

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