Xiaofan Mu
Xiaofan Mu

Reputation: 17

Javascript how to distinguish between mouseDown, click and doubleClick events

I would like to have different handlers for mouseDown, single click and double click events inside a html svg. Now when I click the svg, both mouseDown and click handlers are triggered, and similarly, when double clicking, both click and double click handlers are triggered. Is there a way to solve this problem? Thanks

Update: I would like to use these handlers on svg shapes, specifically mouseDown/Up for drag-and-drop, single click to change shapes, and double click to remove a shape.

Upvotes: 0

Views: 3881

Answers (4)

Mister Jojo
Mister Jojo

Reputation: 22320

you may use event.detail to detect simple or double click,
see in code below if (e.detail === 2) indicate a dblclick event.

// clickSwitcher closure:
const clickSwitcher = ( simpleCLick_fct, doubleClick_fct, clickDelay = 'slow' ) =>
  {
  const cDelay     = (clickDelay==='fast') ? 200 : (clickDelay==='normal') ? 400 : 600; // slow => 600ms
  let   refTimeOut = 0; 

  return (e)=>
    {
    clearTimeout( refTimeOut ); 
    if (e.detail === 2) { doubleClick_fct(e); }
    else                { refTimeOut = setTimeout( simpleCLick_fct, cDelay, e ); }
    }
  };

// sample usage :
const 
  div_1 = document.querySelector('#d1')
, div_2 = document.querySelector('#d2')
  ;
div_1.addEventListener('click', clickSwitcher( d1_SimpleC, d1_DoubleC ) );
div_2.addEventListener('click', clickSwitcher( d2_SimpleC, d2_DoubleC , 'normal') );

let counter = 0
  ;
function d1_SimpleC(e) { console.clear(); console.log( ++counter, 'd1 simple', e.target.id ); }
function d1_DoubleC(e) { console.clear(); console.log( ++counter, 'd1 double -->', e.target.textContent ); }
function d2_SimpleC(e) { console.log( ++counter, 'd2 simple' ); }
function d2_DoubleC(e) { console.log( ++counter, 'd2 double' ); }
#d1 ,
#d2 {
  width      : fit-content;
  height     : fit-content;
  background : aquamarine;
  margin     : 1em;
  padding    : 1em;
  cursor     : pointer;
  }
#d1:hover ,
#d2:hover {
  background : coral;
  }
  

/*css for this snippet */
.as-console-wrapper { max-height:100% !important; top:0; left:50% !important; width:50%; }
.as-console-row     { background-color: yellow; }
.as-console-row::after  { display:none !important; }
<div id="d1"> div 1 </div>
<div id="d2"> div 2 </div>

see also -> What is the max delay between two clicks to trigger a double-click event?

[edit 30/8/24] updated answer:
improved code to make it easier to read, and make it more easily transposable

Upvotes: 1

mashi
mashi

Reputation: 627

dblclick event fires after two click events and after two pairs of mousedown and mouseup events.

Usually, we see such a case when for example selecting/focusing a file by a single click and then executing a file by double click. There is no harm in selecting the same file multiple times.

If you need to distinguish these two events, you can postpone single click handling until you are sure it is not part of the double click, but this will add a delay in handling.

let clicks = 0;
let clickTimer = 0;
const dblClickTimeSpan = 300;

const clickHandler = (e) => {
    clicks++;
    if(clicks === 1) {
    clickTimer = setTimeout(()=>{
        clicks = 0;
        // handle single click, now we are sure it is not a bouble click
        console.log('Single Click.')
    }, dblClickTimeSpan);
    }
    if(clicks === 2) {
        // it is the second click in double-click event
        clearTimeout(clickTimer);
        clicks = 0;
    }
}

myButton.addEventListener('click', clickHandler);
myButton.addEventListener('dblclick', (e) => console.log('Double Click.'));
<button id="myButton">Button</button>

Upvotes: 3

asfandyar24
asfandyar24

Reputation: 84

You can create the click method and using timeout differentiate if there is single click or double click event happening. and in timeout set the difference of 1 or 2 seconds.

Upvotes: 0

olvin
olvin

Reputation: 41

Double click (obviously) consists of two single clicks. When the first click is performed no one knows will there be any second click or not. That's why the first click of a double click produces a "single click event". So there is no way to fix this problem.

The recommended solution is not to use both (single and double click) events on the same control.

Upvotes: 1

Related Questions