js differ click and double click

1.5k Views Asked by At

I am trying to differentiate click and dblclick events by javascript. I tried stopPropagation in dblclick however did not work. hence I coded my own function using setTimeout tries to avoid calling the other when calling one.

/* dblclick differ click 
takes two functions as param and one element 
to bind the event listener on
*/
function cdblclick(click, dblclick, el){
  el.cooled = true;
  el.addEventListener('click', function(){
    if(el.cooled){
      setTimeout(function(){
        if(!el.cdblc){el.cdblc = 0}
        el.cdblc++;
        if(el.cdblc === 1){
          setTimeout(function(){
            if(!el.doubled){
              console.log('click')
              // click();
              el.cdblc = 0;
              el.cooled = true;
              el.doubled = false;
            }
          }, 300);
        }else if(el.cdblc === 2){
          console.log('double')
          // dblclick();
          el.doubled = true;
          el.cdblc = 0;
          el.cooled = true;
        }else{
        }
      }, 250);
    }
  });
}

however, it does not work properly. I will be so glad if you ca give me a hand.


Thanks for the suggestions of divide to two elements, however, I must implement both events on the same element


solution

thanks to all the helps.

/* dblclick differ click 
takes two functions as param and one element 
to bind the event listener on
*/
function cdblclick(click, dblClick, el) {
  let clickedTimes = 0;
  const incrementClick = () => {
    clickedTimes++;
  };
  const reset = () => {
    clickedTimes = 0;
  };
  el.addEventListener('click', e => {
    incrementClick();
    setTimeout(() => {
      if (clickedTimes === 1) {
        click(e);
      } else if (clickedTimes >= 2) {
        dblClick(e);
      }
      reset();
    }, 300);
  });
}
5

There are 5 best solutions below

0
On BEST ANSWER

If you dont want to execute the single click at all in case of double, you can use a timeout like you did. You just have to reset the counter and the timeout properly. You do not reset el.cdblc on your last empty else.

Be aware, that this delays normal clicks.

/* dblclick differ click 
takes two functions as param and one element 
to bind the event listener on
*/
function cdblclick(click, dblclick, el){
  //REM: Storing the values in an object instead of own element properties
  let tObject = {
    Clicks: 0,
    onClick: click,
    onDblClick: dblclick
  };

  //el.cooled = true;
  el.addEventListener('click', function(object){
    object.Clicks += 1;

    //REM: Starting the click..
    if(object.Clicks === 1){
      object.Timeout = window.setTimeout(function(){
        //REM: Execute click if not stopped
        if(typeof object.onClick == 'function'){
          object.onClick()
        };

        //REM: Resetting the click count
        object.Clicks = 0

        /*if(!el.cdblc){el.cdblc = 0}
        el.cdblc++;
        if(el.cdblc === 1){
          setTimeout(function(){
            if(!el.doubled){
              console.log('click')
              // click();
              el.cdblc = 0;
              el.cooled = true;
              el.doubled = false;
            }
        */
      }.bind(this, object), 300)
    }
    //REM: Unless we have triple clicks, there is only double left
    else{
        //REM: Cancel the single click
        window.clearTimeout(object.Timeout);
    
        //REM: Execute double click
        if(typeof object.onDblClick === 'function'){
            object.onDblClick()
          };

        //REM: Resetting the click count
        object.Clicks = 0
        
        /*
          console.log('double')
          // dblclick();
          el.doubled = true;
          el.cdblc = 0;
          el.cooled = true;
       */
    }
  }.bind(el, tObject))
};

document.querySelector('b').onclick = cdblclick(
  function(){console.log('onclick')},
  function(){console.log('ondblclick')},
  document.body
);
<b>Click me</b>

0
On

you can try ondblclick js listner like this :

document.getElementById('click').onclick = function() { console.log("click"); }
document.getElementById('dblclick').ondblclick = function() { console.log("double click"); }
<div>
   <button id="click"> click </button>
   <button id="dblclick"> double click </button>
   
 </div>

0
On

You can try this way to differ click and dbclick:

document.getElementById('click').onclick = function() { 
//do something if click
}
document.getElementById('click').ondblclick = function() { 
//do something if dbclick
}
  
<div>
   <button id="click"> click or dbclick? </button> 
 </div>

0
On

Like this will work.

function cDblClick(click, dblClick, el) {
  let clickedTimes = 0;
  const incrementClick = () => {
    clickedTimes++;
  };
  const reset = () => {
    clickedTimes = 0;
  };

  el.addEventListener('click', () => {
    incrementClick();

    setTimeout(() => {
      if (clickedTimes === 1) {
        click();
      } else if (clickedTimes === 2) {
        dblClick();
      }

      reset();
    }, 300);
  });
}
0
On

Here's a solution where each 'click counter' is specific to each element, so onclick functions outside the element will not be effected...

const singleOrDouble = ({target}) => {
  if (isNaN(target.cn)) {
    target.cn = 1 
  } else {
    target.cn++
  }
  setTimeout(() => {
    if (target.cn == 1) {
     console.log('once')
     target.cn = 0
    }
    if (target.cn > 1) {
      console.log('twice')
      target.cn = 0
    }
  }, 500)  
}
<p onclick="singleOrDouble(event)">Click me</p>