javascriptclickondblclick

js differ click and double click


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

Solution

  • 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>