Javascript拖放触摸设备

joe*_*joe 116 javascript jquery jquery-ui touch

我正在寻找适用于触摸设备的拖放插件.

我想要与jQuery UI插件类似的功能,它允许"droppable"元素.

jqtouch插件支持拖动操作,但没有落下.

是拖放,只支持iPhone/iPad.

任何人都可以指向一个适用于android/ios的拖放插件的方向吗?

...或者有可能更新jqtouch插件的droppability,它已经在Andriod和IOS上运行.

谢谢!

ryu*_*suo 255

您可以使用jQuery UI的用于拖动和与转化鼠标事件到触摸其他库丢弃哪些是你需要什么,我建议库https://github.com/furf/jquery-ui-touch-punch,与这个你从Jquery UI拖放应该在触摸设备上工作

或者您可以使用我正在使用的代码,它还可以将鼠标事件转换为触摸,它就像魔术一样.

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);
}
Run Code Online (Sandbox Code Playgroud)

并在您的document.ready中调用init()函数

这里找到的代码

  • 谢谢你分享这个.但是,您应该赞扬您发布的代码的原作者.http://ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript/ (29认同)
  • 谢谢,在我的Android设备上的东西现在可以拖动了.但是,单击它时不再触发click事件.任何想法如何解决? (10认同)
  • 注意:由于事件监听器是为整个文档注册的,因此该解决方案还禁用了我的Nexus S上的滚动... (9认同)
  • @JohnLandheer 我通过将事件侦听器仅附加到我想要可拖动的对象来解决这个问题,`document.getElementById('draggableContainer').addEventListener(...` (2认同)

E.Z*_*art 21

对于任何想要使用它并保持"点击"功能的人(正如John Landheer在他的评论中提到的那样),你可以通过几个修改来做到这一点:

添加几个全局变量:

var clickms = 100;
var lastTouchDown = -1;
Run Code Online (Sandbox Code Playgroud)

然后将switch语句从原来修改为:

var d = new Date();
switch(event.type)
{
    case "touchstart": type = "mousedown"; lastTouchDown = d.getTime(); break;
    case "touchmove": type="mousemove"; lastTouchDown = -1; break;        
    case "touchend": if(lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms){lastTouchDown = -1; type="click"; break;} type="mouseup"; break;
    default: return;
}
Run Code Online (Sandbox Code Playgroud)

您可能希望根据自己的喜好调整"clickms".基本上它只是在观看"触摸启动",然后通过'touchend'快速模拟点击.


小智 12

谢谢你的上述代码! - 我尝试了几个选项,这是票.我有问题,因为preventDefault阻止了在ipad上的滚动 - 我现在正在测试可拖动的项目,它到目前为止工作得很好.

if (event.target.id == 'draggable_item' ) {
    event.preventDefault();
}
Run Code Online (Sandbox Code Playgroud)


小智 10

我有与gregpress答案相同的解决方案,但我的可拖动项目使用的是类而不是id.它似乎工作.

var $target = $(event.target);  
if( $target.hasClass('draggable') ) {  
    event.preventDefault();  
}
Run Code Online (Sandbox Code Playgroud)

  • 你只是使用了一个不同的选择器的事实并不能保证是一个单独的答案,而是你应该评论@ gregpress的答案. (4认同)
  • @bPratik除非他想要一个更好的格式化答案提供 - 而且他提供了一个完整的代码示例的事实确实需要一个单独的答案.应该留下评论链接到他的答案虽然...... (2认同)

Cod*_*eat 8

旧线程我知道.......

@ryuutatsuo答案的问题在于它还会阻止任何输入或其他必须对"点击"做出反应的元素(例如输入),所以我写了这个解决方案.该解决方案使得可以在任何触摸设备(或cumputer)上使用基于mousedown,mousemove和mouseup事件的任何现有拖放库.这也是一种跨浏览器的解决方案.

我已经在几个设备上进行了测试,它运行速度很快(结合ThreeDubMedia的拖放功能(另请参阅http://threedubmedia.com/code/event/drag)).它是一个jQuery解决方案,因此您只能将它用于jQuery库.我已经使用了jQuery 1.5.1,因为一些较新的函数在IE9及以上版本中无法正常工作(未使用较新版本的jQuery进行测试).

向事件添加任何拖放操作之前,必须先调用此函数:

simulateTouchEvents(<object>);
Run Code Online (Sandbox Code Playgroud)

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

simulateTouchEvents(<object>, true); // ignore events on childs
Run Code Online (Sandbox Code Playgroud)

这是我写的代码.我使用了一些很好的技巧来加速评估事物(见代码).

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;
}; 
Run Code Online (Sandbox Code Playgroud)

它的作用:首先,它将单个触摸事件转换为鼠标事件.它检查事件是否由必须拖动的元素上/中的元素引起.如果它是输入元素,例如input,textarea等,它会跳过翻译,或者如果附加了标准鼠标事件,它也会跳过翻译.

结果:可拖动元素上的每个元素仍然有效.

快乐的编码,greetz,Erwin Haantjes