如何区分鼠标“点击”和“拖动”

我使用jQuery.click来处理Raphaelgraphics上的鼠标点击事件,同时,我需要处理鼠标drag事件,鼠标拖拽包含在Raphael中的mousedownmouseupmousemove

clickdrag很难区分,因为click还包含mousedownmouseup ,那么在Javascript中如何区分鼠标的“单击”和鼠标“拖动”呢?

我认为不同之处在于在拖动中mousedownmouseup之间存在mousedown ,而不是点击。

你可以做这样的事情:

 var flag = 0; var element = xxxx; element.addEventListener("mousedown", function(){ flag = 0; }, false); element.addEventListener("mousemove", function(){ flag = 1; }, false); element.addEventListener("mouseup", function(){ if(flag === 0){ console.log("click"); } else if(flag === 1){ console.log("drag"); } }, false); 

如果你已经在使用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); }); }); 

正如mrjrdnthms在他对已接受的答案的评论中指出的那样,Chrome不再适用(它总是触发mousemove),我已经调整了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函数来自这个答案

这应该很好。 类似于接受的答案(尽pipe使用jQuery),但isDragging标志只有在新的鼠标位置不同于mousedown事件时才会重置。 与接受的答案不同的是,它适用于最近版本的Chrome,无论您是否移动鼠标,都会触发mousemove

 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 = []; }); 

你也可以调整mousemove的坐标检查,如果你想添加一点宽容(即微小的动作作为点击,而不是拖动)。

如果你觉得使用Rxjs :

 var element = $('#drag'); Rx.Observable.merge( Rx.Observable.fromEvent(element, 'mousedown').mapTo(0), Rx.Observable.fromEvent(element, 'mousemove').mapTo(1) ).sample(Rx.Observable.fromEvent(element, 'mouseup')) .subscribe(flag => { if(flag === 0){ console.log("click"); } else if(flag === 1){ console.log("drag"); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://unpkg.com/@reactivex/rxjs@5.4.1/dist/global/Rx.js"></script> <h1 id="drag">drag me!</h1> 

如果只是为了过滤出拖拽的情况,像这样做:

 var moved=false; $(selector).mousedown(function(){moved=false;}).mousemove(function(){moved=true;}).mouseup(function(event){ if(!moved){ // clicked without moving mouse } } 

使用5像素x / y的jQuery来检测拖动:

 var dragging = false; $("body").on("mousedown", function(e) { var x = e.screenX; var y = e.screenY; dragging = false; $("body").on("mousemove", function(e) { if (Math.abs(x - e.screenX) > 5 || Math.abs(y - e.screenY) > 5) { dragging = true; } }); }); $("body").on("mouseup", function(e) { $("body").off("mousemove"); console.log(dragging ? "drag" : "click"); });