在触屏移动设备上启用拖放功能

16

我最近刚入手了一部安卓手机,发现我的网站上的拖放功能无法使用!我知道为什么它不能工作,但有没有人找到解决办法?我正在使用jQuery来实现拖放...


标记正确答案。 - RominaV
6个回答

33

TouchPunch救了我的命。在iPad和Nexus 7上都能使用。谢谢。 - Magnus Smith
TouchPunch非常好用,感谢您提醒我使用这个库。 - nullability
1
虚幻引擎。非常感谢你。可惜你没有得到答案的分数。 - Wesley Skeen
太棒了!出色的小工具。 - fatlog
不是最好的解决方案:如果要拖动的元素占据整个视口,使用jQuery UI Touch Punch会防止文档滚动。甚至对于你想要在容器中隐藏溢出的仅可水平拖动的元素(如可拖动的旋转木马),这可能会成为一个问题。在这种情况下,旋转木马会阻止用户上下滚动文档。我更喜欢jQuery Touch(github.com/ajlkn/jquery.touch),它使得在移动设备上仅能通过触摸进行拖动(鼠标手势可以被过滤),并且不会阻止触摸事件传播(因此,文档可以被滚动)。 - MaxAuray

3
我使用了上面的touchpunch答案,它很好用。不过需要注意一点,我发现在移动Chrome上运行Android设备时,使用网站上的github链接(和上面的链接)并不能正常工作:

SCRIPT: https://raw.github.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js

但是从网站获取的原始、可读源代码确实可以正常工作。截至本文发布日期,这种情况可能已得到修复,但在此期间,也许可以为您节省一些调试周期。

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

2

虽然这是一篇老帖子,但我有一个解决方案,它可以在可拖动元素上响应任何输入或其他元素的“点击”(例如输入)。这个解决方案使得可以在任何触摸设备(或计算机)上使用基于mousedown、mousemove和mouseup事件的任何现有拖放库。这也是一个跨浏览器的解决方案。

我已经在几个设备上测试过,它运行速度很快(与ThreeDubMedia的拖放功能结合使用,详情请参见http://threedubmedia.com/code/event/drag)。这是一个jQuery解决方案,所以你只能用jQuery libs。我用的是jQuery 1.5.1,因为一些新功能在IE9及以上版本中无法正常工作(未测试新版本的jQuery)。

添加任何拖放操作到一个事件之前,你必须先调用这个函数

simulateTouchEvents(<object>);

你可以使用以下语法来阻止所有组件/子项的输入或加速事件处理:

您还可以通过使用以下语法来阻止所有组件/子项的输入或加速事件处理:

simulateTouchEvents(<object>, true); // ignore events on childs

这是我写的代码。我使用了一些巧妙的技巧来加速评估(请参见代码)。

function simulateTouchEvents(oo,bIgnoreChilds)
{
 if( !$(oo)[0] )
  { return false; }

 if( !window.__touchTypes )
 {
   window.__touchTypes  = {touchstart:'mousedown',touchmove:'mousemove',touchend:'mouseup'};
   window.__touchInputs = {INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,'input':1,'textarea':1,'select':1,'option':1};
 }

$(oo).bind('touchstart touchmove touchend', function(ev)
{
    var bSame = (ev.target == this);
    if( bIgnoreChilds && !bSame )
     { return; }

    var b = (!bSame && ev.target.__ajqmeclk), // Get if object is already tested or input type
        e = ev.originalEvent;
    if( b === true || !e.touches || e.touches.length > 1 || !window.__touchTypes[e.type]  )
     { return; } //allow multi-touch gestures to work

    var oEv = ( !bSame && typeof b != 'boolean')?$(ev.target).data('events'):false,
        b = (!bSame)?(ev.target.__ajqmeclk = oEv?(oEv['click'] || oEv['mousedown'] || oEv['mouseup'] || oEv['mousemove']):false ):false;

    if( b || window.__touchInputs[ev.target.tagName] )
     { return; } //allow default clicks to work (and on inputs)

    // https://developer.mozilla.org/en/DOM/event.initMouseEvent for API
    var touch = e.changedTouches[0], newEvent = document.createEvent("MouseEvent");
    newEvent.initMouseEvent(window.__touchTypes[e.type], true, true, window, 1,
            touch.screenX, touch.screenY,
            touch.clientX, touch.clientY, false,
            false, false, false, 0, null);

    touch.target.dispatchEvent(newEvent);
    e.preventDefault();
    ev.stopImmediatePropagation();
    ev.stopPropagation();
    ev.preventDefault();
});
 return true;
}; 

它的作用: 首先,它将单点触摸事件转换为鼠标事件。它检查事件是否由必须拖动的元素上/内的元素引起。如果是像input、textarea等输入元素,则跳过翻译;或者如果一个标准的鼠标事件附加到它上面,它也会跳过翻译。

结果: 可拖动元素上的每个元素仍然可以正常工作。

愉快的编码,问候, Erwin Haantjes


1
谢谢Erwin,这个实现真的很棒,一次就成功了,不需要调整!在ELO触摸屏电脑上测试通过。 - Jonathan Lafleur

1

iPhone至少有一些事件,如ontouchstart、ontouchend等。这些是Webkit的一部分,但是关于Android的信息比iPhone要少得多。我认为这个问题的答案是拖放功能需要使用那些事件而不是你通常使用的事件,或者需要同时使用两者。

这篇文章可能会引起您的兴趣 - http://backtothecode.blogspot.com/2009/10/javascript-touch-and-gesture-events.html


链接已失效。 - bvdb

0

有一个jQuery拖放插件,支持移动设备/触摸屏设备:

http://plugins.jquery.com/project/mobiledraganddrop

在移动设备上,您可以轻触以拾取物品并轻触以选择放置位置。这样可以避免拖动操作被设备/浏览器劫持的问题。

上述库在其演示页面上有4个不同的“拖动”示例。请注意,它们都无法在我的iPad 2上正常工作。 - Alex Gray
@alex gray,发现的很好。我已经针对3.0.1提出了一个错误报告。 - Fenton
在iPad2上仍无法正常工作,并且在桌面Webkit浏览器中存在大量的视觉伪影/功能不完整。http://cl.ly/0a3a0X3o3e462O3g2P2O - Alex Gray
我没有iPad2,所以无法在其上进行测试 - 但在iPhone上可以。另一件事是,由于它是开源的,如果你在jquery.com上报告了一个错误,有人会修复它。我认为webkit问题现在已经解决了 - 我认为mousedown和touchstart的组合会导致同一事件触发多次。 - Fenton

0

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