Reputation: 17
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
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
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
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
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