触摸设备的拖放

141988 次浏览

你可以使用 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);
}

在 document.ready 中,只需调用 init ()函数

给你找到的代码

谢谢上面的密码!我试了好几种方法,这是最好的办法。我有一个问题就是阻止 ipad 上的滚动-我现在正在测试可拖动的项目,到目前为止它工作得很好。

if (event.target.id == 'draggable_item' ) {
event.preventDefault();
}

我有与 Gregpress 回答相同的解决方案,但我的可拖动项目使用的是类而不是 id。看起来有用。

var $target = $(event.target);
if( $target.hasClass('draggable') ) {
event.preventDefault();
}

对于任何想要使用这个并保持“点击”功能的人(正如 John Landheer 在他的评论中提到的) ,你只需要做几处修改就可以做到:

再加上几个全球性的:

var clickms = 100;
var lastTouchDown = -1;

然后将 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;
}

你可能需要根据自己的口味调整“点击”。基本上,它只是观察一个“触摸开始”,紧接着是一个“触摸终端”来模拟点击。

我认识的一条老线。

@ ryuutatsuo 的问题在于,它还会阻塞任何必须对“点击”(例如输入)作出反应的输入或其他元素,因此我编写了这个解决方案。这个解决方案使得在任何触摸设备(或计算机)上使用任何基于鼠标向下、鼠标移动和鼠标向上事件的现有拖放库成为可能。这也是一个跨浏览器的解决方案。

我已经在几个设备上进行了测试,它工作得很快(结合了 Three DubMedia 的拖放特性(也参见 http://threedubmedia.com/code/event/drag))。它是一个 jQuery 解决方案,因此您只能在 jQuery 库中使用它。我之所以使用 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