我正在尝试开发一种可在桌面和触控设备(如ipad / iphone)上运行的拖放功能。
通过简单地绑定给定DOM元素上的touchstart
,touchmove
和touchend
事件,我没有遇到实现“拖动”的问题。
我正在努力解决的是如何实现'可放置'部分。换句话说,我如何弄清楚我的可拖动哪些DOM元素掉了'过'??
您可以假设使用jQuery。但是,我没有使用jQueryUI - 它目前不适用于触摸事件。
答案 0 :(得分:1)
显然,你的页面会有很多DOM元素。因此,我建议使用HTML5数据属性标记那些可能有某些内容掉落的内容,即。然后,在touchend事件处理程序中,使用jQuery的.offset()和.height()以及.width()组合获取文档中已删除元素的位置。完成后,循环显示标记为“dropReceiver”的div,以获得他们的位置。然后,您可以测试被删除元素的位置是否与其中一个dropReceiver元素的位置相交。
例如: draggedElement.addEventListener(“touchend”,function(){ var draggedX1 = $(this).offset()。left; var draggedX2 = $(this).width()+ draggedX1; var draggedY1 = $(this).offset()。top; var draggedY2 = $(this).height()+ draggedY1;
$('div[data-dropReceiver=true]').each(function(){
var droppedX1 = $(this).offset().left;
var droppedX2 = $(this).width() + droppedX1;
var droppedY1 = $(this).offset().top;
var droppedY2 = $(this).height() + droppedY1;
if((draggedX1 > droppedX1 && draggedX1 < droppedX2 && draggedY1 > droppedY1 && draggedY1 < draggedY2) || (draggedX2 > droppedX1 && draggedX2 < droppedX2 && draggedY2 > droppedY1 && draggedY2 < draggedY2)){
var dropReceiver = $(this);
//do stuff with the dragged element and the element it was dropped on
break;
}
});
我很确定我的冗长if语句是否正确,但我可能已经写了一两个错误,所以如果你发现这段代码不起作用,请确保重新检查它。
此外,您需要实施的最终解决方案很可能会更复杂一些。如果拖动的元素可能与多个可能的dropReceiver重叠,则一旦找到交集,就不能简单地突破.each()循环。相反,您将需要实际计算元素相交多少,并最终将真正的dropReceiver指定为与拖动元素具有最大交集量的那个。但是,我上面提供的代码已经为您提供了执行此操作所需的工具,因为它实际上提供了每个元素的边界矩形的坐标。
编辑 - 回应OP对此答案的第一次评论
似乎没有可能让dropReceivers触发触摸事件。即使你将一个touchstart事件绑定到它们,它也不会触发,因为被拖动的元素不是dropReceiver的子元素(我假设),并且它必须具有绝对定位才能被拖动。这意味着它总是在dropReceivers之上分层(比如更高的z-index)。因此,它将始终阻止用户的手指实际触摸dropReceiver。因此,touchstart事件永远不会在dropReceiver上触发。
然而,我确实认为有一个比我想出的更简单的解决方案。 Mobile Safari上的触摸事件包括该触摸的x和y坐标。因此,除了测试拖动元素和dropReceiver的交集之外,您需要做的就是测试触点是否落在dropReceiver的范围内,即
if(touchpoint.x > droppedX1 && touchpoint.x < droppedX2 && touchpoint.y > droppedY1 && touchpoint.y < droppedY2){
//you've found the dropped element
}
这绝对是一个更好的解决方案,因为它消除了拖动元素可能与两个dropReceivers相交的更复杂的情况。由于您正在测试单个触摸点,因此它将始终位于仅一个dropReceiver的范围内,因此不需要进行交叉区域比较。
答案 1 :(得分:0)
我建议您考虑使用jQueryUI,这样您就不必重新发明轮子了。您可以使用jQuery.ui.touch-punch plug-in使用jQueryUI解决触摸事件问题,{{3}}将鼠标事件映射到触摸事件。