我正在使用jQuery UI Sortable。
我正在开发一个仅限移动设备的网站,所以我查看了如何将触摸事件映射到鼠标事件以使其工作,最后使用了一些code by Oleg Slobodskoi。
这看起来效果很好。但是,在移动设备上(我正在使用iPhone进行测试,但它也会在iPhone模拟器上进行测试),当您尝试移动第二个项目(即在您已经对其中一个进行排序后对下一个项目进行排序)时,位置左右偏移大约元素的宽度。
当我第二次尝试拖动其中一个粉红色的盒子,而不是出现在我的手指下面并随之移动时,它开始绕着一个盒子的宽度,向左或向右,然后< em>在我的手指下跳。
我已经设置了example on jsFiddle。点击 attach 按钮,将jQuery Sortable添加到列表项中。
我尝试了很多东西,包括玩change
事件并试图重新调整它,但我无法让它可靠地工作。
如何解决此问题?
答案 0 :(得分:12)
这个超级简单的解决方案。我希望我能说这很简单,但是没有...它需要一段时间。
为了澄清症状,最初拖动的元素始终是在后续拖动上拖动的元素。如果您开始拖动b
,则后续拖动b
是始终移动的拖动。同样适用于a
和c
。
这让我怀疑这个事件是否正在被“回收”。我确认pageX
(和pageY
)事件的touchstart
和touchmove
值是正确的,但在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();