javascript - How to distinguish mouse "click" and "drag"

ID : 20259

viewed : 9

Tags : javascriptdom-eventsjavascript

Top 5 Answer for javascript - How to distinguish mouse "click" and "drag"

vote vote

93

I think the difference is that there is a mousemove between mousedown and mouseup in a drag, but not in a click.

You can do something like this:

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)

vote vote

82

Cleaner ES2015

let drag = false;    document.addEventListener('mousedown', () => drag = false);  document.addEventListener('mousemove', () => drag = true);  document.addEventListener('mouseup', () => console.log(drag ? 'drag' : 'click'));

Didn't experience any bugs, as others comment.

vote vote

80

In case you are already using 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);   }); }); 
vote vote

60

All these solutions either break on tiny mouse movements, or are overcomplicated.

Here is a simple adaptable solution using two event listeners. Delta is the distance in pixels that you must move horizontally or vertically between the up and down events for the code to classify it as a drag rather than a click. This is because sometimes you will move the mouse or your finger a few pixels before lifting it.

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!   } }); 
vote vote

59

This should work well. Similar to the accepted answer (though using jQuery), but the isDragging flag is only reset if the new mouse position differs from that on mousedown event. Unlike the accepted answer, that works on recent versions of Chrome, where mousemove is fired regardless of whether mouse was moved or not.

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

You may also adjust the coordinate check in mousemove if you want to add a little bit of tolerance (i.e. treat tiny movements as clicks, not drags).

Top 3 video Explaining javascript - How to distinguish mouse "click" and "drag"

Related QUESTION?