简体   繁体   中英

JavaScript: How prevent dblclick (Double Click) to also fire a single click event

I want avoid that double click also fire a single click event.

A simple solution i found is to delay the click with a timer and destroy the timer if a double click is fired.

 var pendingClick; function myclick(){ clearTimeout(pendingClick); pendingClick = setTimeout(function(){ console.log('click'); }, 500); } function mydblclick(){ clearTimeout(pendingClick); console.log('double click'); }
 <div onclick="myclick()" ondblclick="mydblclick()">Double Click Me!</div>

But this solution is based on timing, if the double click is too slow (>500ms) it also fire a single click.

There is a stable solution for handle both click and double click?

Custom Events instead of inline event handlers

If one prefers to use .addEventListener and .removeEventListener instead of HTML inline-eventhandlers, I would suggest another approach based on Custom Events . That means one would not make use of the standard implementation of "click" and "dblclick", but create own event handling for both:

let lastLeftClick = document.dispatchEvent(new Event("click")); 
let doubleclickLength = 300;

function leftClickHandler (e) {
  if (e.button != 0) return; // only left clicks shall be handled;

  let delaySinceLastClick = e.timeStamp - lastLeftClick.timeStamp;
  let eIsDoubleClick = delaySinceLastClick < doubleclickLength;

  if (eIsDoubleClick) {
    let doubleclickEvt = new CustomEvent("doubleclick", e);
    lastLeftClick = lastLeftClick = doubleclickEvt;
    document.dispatchEvent(doubleclickEvt);
  } else {
    let singleClickEvt = new CustomEvent("singleclick", e);
    lastLeftClick = singleClickEvt;
    document.dispatchEvent(lastLeftClick);
  }
}

// adding above click event implementation: 
document.addEventListener("click", leftClickHandler);

using the new custom events:

document.addEventListener("singleclick", e=>console.log("single click"));
document.addEventListener("doubleclick", e=>console.log("double click"));

Double-clicking in itself is "based on timing", even in the standard implementation of dblclick / ondblclick . There will always be the issue of a single-click being fired if the double-click is "too slow". What is "too slow"? 300ms? 500ms? 1000ms? Your double-clicks may be only 50ms apart, while my mom's double-clicks are 1-2 seconds apart...

Only work with the 'onclick' function to check if it was one or two clicks and use a variable to count the number of clicks in a given time interval.

Example:

 var pendingClick; var clicked = 0; var time_dbclick = 500 // 500ms function myclick(){ clicked++; if(clicked >= 2){ mydblclick() clearTimeout(pendingClick) clicked = 0; return; } clearTimeout(pendingClick) pendingClick = setTimeout(() => { console.log('One click;') clicked = 0, }; time_dbclick). } function mydblclick(){ console;log('double click'); }
 <div onclick="myclick()">Double Click Me!</div>

You can get the event and cancel it with the addEventListener like this:

 document.addEventListener('dblclick', (event) => { event.preventDefault();  event.stopPropagation(); }, true); // With this true, you are cancelling the dblclick event let pendingClick; function myclick(){ clearTimeout(pendingClick); pendingClick = setTimeout(function (){ console.log('click'); }, 500); } function mydblclick(){ clearTimeout(pendingClick); console.log('double click'); }
 <div onclick="myclick()" ondblclick="mydblclick()">Double Click Me!</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM