jQuery UI Sortable在触摸屏设备上发生了什么?

时间:2011-10-13 06:37:24

标签: jquery jquery-ui mobile touch jquery-ui-sortable

我正在使用jQuery UI Sortable

我正在开发一个仅限移动设备的网站,所以我查看了如何将触摸事件映射到鼠标事件以使其工作,最后使用了一些code by Oleg Slobodskoi

这看起来效果很好。但是,在移动设备上(我正在使用iPhone进行测试,但它也会在iPhone模拟器上进行测试),当您尝试移动第二个项目(即在您已经对其中一个进行排序后对下一个项目进行排序)时,位置左右偏移大约元素的宽度。

Example

当我第二次尝试拖动其中一个粉红色的盒子,而不是出现在我的手指下面并随之移动时,它开始绕着一个盒子的宽度,向左或向右,然后< em>在我的手指下跳。

我已经设置了example on jsFiddle。点击 attach 按钮,将jQuery Sortable添加到列表项中。

我尝试了很多东西,包括玩change事件并试图重新调整它,但我无法让它可靠地工作。

如何解决此问题?

2 个答案:

答案 0 :(得分:12)

这个超级简单的解决方案。我希望我能说这很简单,但是没有...它需要一段时间。

为了澄清症状,最初拖动的元素始终是在后续拖动上拖动的元素。如果您开始拖动b,则后续拖动b是始终移动的拖动。同样适用于ac

这让我怀疑这个事件是否正在被“回收”。我确认pageX(和pageY)事件的touchstarttouchmove值是正确的,但在Sortable中到达_mouseDown的值是错误的。所以,我去了jquery.ui.mouse.js并在那里看了_mouseDown。我确认正确的值正在通过,但处理程序正在该方法顶部的此行退出:

// don't let more than one widget handle mouseStart
if( mouseHandled ) { return };

所以,我开始关注mouseHandled。只有一行将其重置为false - 顶部的以下监听器:

$( document ).mouseup( function( e ) {
    mouseHandled = false;
});

我意识到我必须亲近。我回顾了您正在使用的兼容性加载项中的_touchEnd方法:

_touchEnd: function(event) {
   this.element.unbind("touchmove." + this.widgetName).unbind("touchend." + this.widgetName);
   this._mouseUp(event);
}, 

请注意,_mouseUp仅在小部件本身上调用 - 而不是document!因此,显然mouseHandled从未被重置。因此,我向document添加了_touchEnd发送行:

_touchEnd: function(event) {
   this.element.unbind("touchmove." + this.widgetName).unbind("touchend." + this.widgetName);
   this._mouseUp(event);
   $(document).trigger('mouseup', event);
}, 

presto ,一切正常。

因此,总而言之,这一行是神奇的:

$(document).trigger('mouseup', event);

工作分叉小提琴here [direct link for iOS viewing]。


注意:我也改变了这一行:

/ iPad | iPhone /.test(navigator.userAgent) && (function($) {

要:

/iPad|iPhone|iPod/.test(navigator.userAgent) && (function($) {

因为它无法正常使用空格,您应该支持iPod touch。

答案 1 :(得分:0)

还有一件重要的事情。 一切都很好,但前提是我们不向下滚动页面。 问题是Y触摸位置是相对于窗口顶部而不是文档的位置。 我已经解决了这一问题:

event.pageY = target.clientY;

对此:

event.pageY = target.clientY + $(window).scrollTop();