Old thread I know.......
Problem with the answer of @likwid_t is that it blocks also any input or other element that has to react on 'clicks' (for example inputs), so i wrote this solution. 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