enabling drag and drop on a touchscreen mobile device

34,614

Solution 1

I used jQuery UI touch punch - it works by hacking the mousedown, mouseup features and replaces them with touchstart, touchend etc.

ABOUT: http://touchpunch.furf.com/

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

CODE:

include:

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

after your jquery UI script file in your header.

Solution 2

I used the touchpunch answer above and it worked great. One note on it, though. I found that using the github link on the site (and above):

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

did not work for Android devices running mobile Chrome, but the raw, human readable source from the site did work. This is as of the date of this posting, it may get fixed of course, but in the mean time maybe it will save you a few cycles of debugging.

Solution 3

Old thread I know.......

I have here an solution that respects any input or other element that has to react on 'clicks' (for example inputs) on a draggable element. This solution made it possible to use any existing drag and drop library that is based upon mousedown, mousemove and mouseup events on any touch device (or cumputer). This is also a cross-browser solution.

I have tested in on several devices and it works fast (in combination with the drag and drop feature of ThreeDubMedia (see also http://threedubmedia.com/code/event/drag)). It is a jQuery solution so you can use it only with jQuery libs. I have used jQuery 1.5.1 for it because some newer functions don't work properly with IE9 and above (not tested with newer versions of jQuery).

Before you add any drag or drop operation to an event you have to call this function first:

simulateTouchEvents(<object>);

You can also block all components/children for input or to speed up event handling by using the following syntax:

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

Here is the code i wrote. I used some nice tricks to speed up evaluating things (see code).

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;
}; 

What it does: At first, it translates single touch events into mouse events. It checks if an event is caused by an element on/in the element that must be dragged around. If it is an input element like input, textarea etc, it skips the translation, or if a standard mouse event is attached to it it will also skip a translation.

Result: Every element on a draggable element is still working.

Happy coding, greetz, Erwin Haantjes

Solution 4

The iPhone at least has certain events such as ontouchstart, ontouchend, etc. These are part of webkit, but there is much less information with regards Android than iPhone. I think the answer to this question is that the drag and drop functionality needs to use those events rather than the events you would normally use, or needs to use both.

This article may be of interest - http://backtothecode.blogspot.com/2009/10/javascript-touch-and-gesture-events.html

Share:
34,614
danwoods
Author by

danwoods

Javascript developer working as front-end engineer.

Updated on June 02, 2020

Comments

  • danwoods
    danwoods almost 4 years

    I just recently got an android phone and found that the drag and drop on my site doesn't work! I understand why it wouldn't, but has anyone found a solution to this? I'm using JQuery to implement the D & D...