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

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


当前回答

正如mrjrdnthms在他对接受的答案的评论中指出的那样,这不再适用于Chrome(它总是触发鼠标移动),我已经改编了Gustavo的答案(因为我使用jQuery)来解决Chrome的行为。

var currentPos = [];

$(document).on('mousedown', function (evt) {

   currentPos = [evt.pageX, evt.pageY]

  $(document).on('mousemove', function handler(evt) {

    currentPos=[evt.pageX, evt.pageY];
    $(document).off('mousemove', handler);

  });

  $(document).on('mouseup', function handler(evt) {

    if([evt.pageX, evt.pageY].equals(currentPos))
      console.log("Click")
    else
      console.log("Drag")

    $(document).off('mouseup', handler);

  });

});

Array.prototype.equals函数来自这个答案

其他回答

这应该能很好地工作。类似于已接受的答案(虽然使用jQuery),但只有当新的鼠标位置与mousedown事件上的位置不同时,isdrag标志才会重置。与公认的答案不同,这适用于最新版本的Chrome,无论鼠标是否移动,鼠标移动都会被触发。

var isDragging = false;
var startingPos = [];
$(".selector")
    .mousedown(function (evt) {
        isDragging = false;
        startingPos = [evt.pageX, evt.pageY];
    })
    .mousemove(function (evt) {
        if (!(evt.pageX === startingPos[0] && evt.pageY === startingPos[1])) {
            isDragging = true;
        }
    })
    .mouseup(function () {
        if (isDragging) {
            console.log("Drag");
        } else {
            console.log("Click");
        }
        isDragging = false;
        startingPos = [];
    });

你也可以在鼠标移动中调整坐标检查,如果你想增加一点公差(即将微小的移动视为点击,而不是拖动)。

对于OSM地图上的公共操作(单击时放置标记),问题是:1)如何确定鼠标向下的持续时间->向上(您无法想象为每次单击创建一个新的标记)2)鼠标向下移动期间->向上(即用户正在拖动地图)。

const map = document.getElementById('map');

map.addEventListener("mousedown", position); 
map.addEventListener("mouseup", calculate);

let posX, posY, endX, endY, t1, t2, action;

function position(e) {

  posX = e.clientX;
  posY = e.clientY;
  t1 = Date.now();

}

function calculate(e) {

  endX = e.clientX;
  endY = e.clientY;
  t2 = (Date.now()-t1)/1000;
  action = 'inactive';

  if( t2 > 0.5 && t2 < 1.5) { // Fixing duration of mouse down->up

      if( Math.abs( posX-endX ) < 5 && Math.abs( posY-endY ) < 5 ) { // 5px error on mouse pos while clicking
         action = 'active';
         // --------> Do something
      }
  }
  console.log('Down = '+posX + ', ' + posY+'\nUp = '+endX + ', ' + endY+ '\nAction = '+ action);    

}

其实就是这么简单

var dragged = false
window.addEventListener('mousedown', function () { dragged = false })
window.addEventListener('mousemove', function () { dragged = true })
window.addEventListener('mouseup', function() {
        if (dragged == true) { return }
        console.log("CLICK!! ")
})

老实说,您不希望添加允许小移动的阈值。以上是正确的,正常的,点击所有桌面界面的感觉。

试试吧。

如果愿意,可以轻松添加事件。

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

下面是一个使用两个事件侦听器的简单适应性解决方案。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!
  }
});

来自@Przemek的回答,

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