我使用jQuery。点击来处理Raphael图形上的鼠标点击事件,同时,我需要处理鼠标拖动事件,鼠标拖动在Raphael中由鼠标下拉,鼠标上拉和鼠标移动组成。

很难区分点击和拖动,因为点击也包含鼠标下拉和鼠标上拉,我怎么能区分鼠标“点击”和鼠标“拖动”然后在Javascript?


当前回答

有同样的问题,最近在一个树列表中,用户可以点击项目或拖动它,使这个小指针类,并把它放在我的utils.js

function Pointer(threshold = 10) {
  let x = 0;
  let y = 0;

  return {
    start(e) {
     x = e.clientX;
     y = e.clientY;
    },

    isClick(e) {
      const deltaX = Math.abs(e.clientX - x);
      const deltaY = Math.abs(e.clientY - y);
      return deltaX < threshold && deltaY < threshold;
    }
  }
}

下面你可以看到它的工作原理:

function Pointer(threshold = 10) { let x = 0; let y = 0; return { start(e) { x = e.clientX; y = e.clientY; }, isClick(e) { const deltaX = Math.abs(e.clientX - x); const deltaY = Math.abs(e.clientY - y); return deltaX < threshold && deltaY < threshold; } } } const pointer = new Pointer(); window.addEventListener('mousedown', (e) => pointer.start(e)) //window.addEventListener('mousemove', (e) => pointer.last(e)) window.addEventListener('mouseup', (e) => { const operation = pointer.isClick(e) ? "Click" : "Drag" console.log(operation) })

其他回答

来自@Przemek的回答,

函数listenClickOnly(元素,回调,阈值=10){ 让拖动= 0; 元素。addEventListener('mousedown', () => drag = 0); 元素。addEventListener('mousemove', () => drag++); 元素。addEventListener('mouseup', e => { 如果(拖动<阈值)回调(e); }); } listenClickOnly ( 文档, () => console.log('click'), 10 );

我认为区别在于,在拖拽中,mousedown和mouseup之间有一个鼠标移动,但在点击中没有。

你可以这样做:

const element = document.createElement('div') element.innerHTML = 'test' document.body.appendChild(element) let moved let downListener = () => { moved = false } element.addEventListener('mousedown', downListener) let moveListener = () => { moved = true } element.addEventListener('mousemove', moveListener) let upListener = () => { if (moved) { console.log('moved') } else { console.log('not moved') } } element.addEventListener('mouseup', upListener) // release memory element.removeEventListener('mousedown', downListener) element.removeEventListener('mousemove', moveListener) element.removeEventListener('mouseup', upListener)

如果你已经在使用jQuery:

var $body = $('body');
$body.on('mousedown', function (evt) {
  $body.on('mouseup mousemove', function handler(evt) {
    if (evt.type === 'mouseup') {
      // click
    } else {
      // drag
    }
    $body.off('mouseup mousemove', handler);
  });
});

所有这些解决方案要么在微小的鼠标移动上失效,要么过于复杂。

下面是一个使用两个事件侦听器的简单适应性解决方案。Delta是您必须在上下事件之间水平或垂直移动的距离(以像素为单位),以便代码将其归类为拖拽而不是单击。这是因为有时你会在抬起鼠标或手指之前移动几个像素点。

const delta = 6;
let startX;
let startY;

element.addEventListener('mousedown', function (event) {
  startX = event.pageX;
  startY = event.pageY;
});

element.addEventListener('mouseup', function (event) {
  const diffX = Math.abs(event.pageX - startX);
  const diffY = Math.abs(event.pageY - startY);

  if (diffX < delta && diffY < delta) {
    // Click!
  }
});

清洁ES2015

Let drag = false; 文档。addEventListener('mousedown', () => drag = false); 文档。addEventListener('mousemove', () => drag = true); 文档。addEventListener('mouseup', () => console.log(拖动?'拖动':'点击'));

正如其他人评论的那样,没有遇到任何bug。