ipad / iphone droppable实现 - 检测元素被触摸

时间:2011-07-23 13:14:50

标签: jquery web-applications

我正在尝试开发一种可在桌面和触控设备(如ipad / iphone)上运行的拖放功能。

通过简单地绑定给定DOM元素上的touchstarttouchmovetouchend事件,我没有遇到实现“拖动”的问题。

我正在努力解决的是如何实现'可放置'部分。换句话说,我如何弄清楚我的可拖动哪些DOM元素掉了'过'??

您可以假设使用jQuery。但是,我没有使用jQueryUI - 它目前不适用于触摸事件。

2 个答案:

答案 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}}将鼠标事件映射到触摸事件。