鼠标拖动选择不适用于触摸设备。我怎样才能使它成为可能?

Posted

技术标签:

【中文标题】鼠标拖动选择不适用于触摸设备。我怎样才能使它成为可能?【英文标题】:The mouse drag selection does not work on touch devices. How can I make it possible? 【发布时间】:2016-02-29 07:27:02 【问题描述】:

鼠标拖动选择不适用于触控设备。我该如何解决这个问题。请检查我的小提琴

http://jsfiddle.net/Brv6J/3/

$(function () 
    var isMouseDown = false;
    $("#our_table td")
        .mousedown(function () 
            isMouseDown = true;
            $(this).toggleClass("highlighted");
            return false; // prevent text selection
        )
        .mouseover(function () 
            if (isMouseDown) 
                $(this).toggleClass("highlighted");
            
        );
    $(document)
        .mouseup(function () 
            isMouseDown = false;
        );
);

【问题讨论】:

有单独的触摸事件用于移动设备:developer.mozilla.org/en-US/docs/Web/API/Touch_events 【参考方案1】:

给元素附加触摸事件,例如touchstart、touchend、touchmove。 例如,

$("#our_table td")
.touchstart(function () 
    isMouseDown = true;
    $(this).toggleClass("highlighted");
    return false; // prevent text selection
)
.touchmove(function () 
    if (isMouseDown) 
        $(this).toggleClass("highlighted");
    
);

【讨论】:

请提供小提琴 我认为 jQuery 中的触摸事件只能与 .on() 结合使用。【参考方案2】:

简介 1

我认为您不能在同一个脚本中制作桌面版和移动版。 在这个答案中,我只关注mobile 版本,因为您拥有桌面。只需检查您使用的是移动设备还是桌面设备并刷新正确的脚本。

简介2

这个问题的挑战是:

    mouse 事件相比,touch 事件很少。 与返回鼠标正在移动的当前节点的mousemove事件相比,touchmove返回您开始移动的元素。也就是说,如果你从节点a开始,移动到节点bevent.target仍然返回节点a

实际答案

为了解决这些问题,我编写了代码检查 touchstarttouchmove 中的元素正在移动,然后在正确的元素上进行切换。

// first - store the coords of all the cells for the position check
var matrix = $('#our_table td').map(function()
  var e = $(this),
      o = e.offset(),
      w = e.width(),
      h = e.height();
  
  return 
    top: o.top,
    left: o.left,
    right: o.left + w,
    bottom: o.top + h,
    e: e
  
).get();

var currentTarget = $(),
    activeTarget = $();


var touchF = function(e) 
   var touch = e.originalEvent.touches[0];
   currentTarget = getCurrent(
       
         clientX: touch.clientX,
         clientY: touch.clientY
       
     );
  
    // if the touch is in one of the cells and it's disfferent than the last touch cell
    if (currentTarget && currentTarget != activeTarget) 
      activeTarget = currentTarget;
      activeTarget.toggleClass('highlighted');
    
  

$('#our_table').bind(
  touchstart: touchF,
  touchmove: touchF
);

function getCurrent(touch) 
  // check if the touch coords are in the position of one of the cells and which one
  var a = matrix.filter(function(obj) 
    var b = (
      touch.clientX > obj.left &&
      touch.clientX < obj.right &&
      touch.clientY < obj.bottom &&
      touch.clientY > obj.top
    );
    
    return b;
  );
  
  return a.length > 0 ? a[0].e : null;
table td 
  width:100px;
  height:100px;
  text-align:center;
  vertical-align:middle;
  background-color:#ccc;
  border:1px solid #fff;


table td.highlighted 
  background-color:#999;
<table cellpadding="0" cellspacing="0" id="our_table">
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
  </tr>
  <tr>
    <td>d</td>
    <td>e</td>
    <td>f</td>
  </tr>
  <tr>
    <td>g</td>
    <td>h</td>
    <td>i</td>
  </tr>
</table>

小提琴:http://jsbin.com/favobu

【讨论】:

以上是关于鼠标拖动选择不适用于触摸设备。我怎样才能使它成为可能?的主要内容,如果未能解决你的问题,请参考以下文章

UIImagePickerController 允许选择方形图像。但是我怎样才能使它成为 16:9?

为啥取消选择不适用于可选择和可拖动的多个项目

触控设备上的可拖动属性

如何为触摸屏制作可拖动项目

SpriteKit - 鼠标在 Sprite 拖动时捕捉到中心

从 webview 内容复制和粘贴仅适用于键盘快捷键(不适用于鼠标或触摸)