0

I have a click listener on a DOM element (no jQuery):

element.addEventListener('click', (e) => {
// some code
});

and obviously when I click, the code runs and everything is fine.

The problems is that when I double click, the code runs twice and I don't want this behavior (when I double click I want it to act like a single click and run the code once).

  • when u click, you can disable the element after completion enable the element accordingly – Deepak Sharma Sep 20 '18 at 07:00
  • maybe you should try doing the same code with a dblclick event, with `e.preventDefault();` in the code - all that in addition to your current code – Roysh Sep 20 '18 at 07:02
  • Possible duplicate of [prevent double click on button in javascript](https://stackoverflow.com/questions/30506762/prevent-double-click-on-button-in-javascript) – Philipp Meissner Sep 20 '18 at 07:04
  • @Roysh I tried that using `stopPropagation` and related, but I couldn't get it to work. I think the `dblclick` will always trigger *after* its related `click` event runs. – CertainPerformance Sep 20 '18 at 07:06

5 Answers5

2

One possibility is to use Date to check to see if the last click that triggered the function proper was less than 1 second ago:

const element = document.querySelector('div');
let lastClick = 0;
element.addEventListener('click', (e) => {
  const thisClick = Date.now();
  if (thisClick - lastClick < 1000) {
    console.log('quick click detected, returning early');
    return;
  }
  lastClick = thisClick;
  console.log('click');
});
<div>click me</div>

If you want the function proper to run only once the last click was more than 1 second ago (rather than the last function proper run being more than one second ago), change it so that lastClick is assigned to inside the if (thisClick - lastClick < 1000) { conditional:

const element = document.querySelector('div');
let lastClick = 0;
element.addEventListener('click', (e) => {
  const thisClick = Date.now();
  if (thisClick - lastClick < 1000) {
    console.log('quick click detected, returning early');
    lastClick = thisClick;
    return;
  }
  lastClick = thisClick;
  console.log('click');
});
<div>click me</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • I would use a timeout instead to make it more straightforward. – Adam Sep 20 '18 at 07:03
  • Might not be the most elegant solution, but that would sure work! Good idea – Roysh Sep 20 '18 at 07:03
  • While this solution definitely works, I really do believe using a `button` as the element to be clicked and use its built-in `disabled` state is a better approach. Not only is it a well-tested behaviour, but it also saves a whole lot of code. – Philipp Meissner Sep 20 '18 at 07:06
  • @PhilippMeissner If the element in question can be counted on to be a button, sure, but that's not guaranteed, which is why I went this route instead. – CertainPerformance Sep 20 '18 at 07:07
  • 1
    @PhilippMeissner I don't think disabling the button after it's clicked once is good UX practice. Although that would definitely solve the problem, it's just not the behavior you'd expect from a button. – Adam Sep 20 '18 at 07:09
  • Is there a way I can check this faster, like even less than a second (like if the second is 1000, maybe check every 500ms, half a second)? because if I click the button really a lot the code gets performed twice. – Kevin M. Mansour May 30 '23 at 14:00
  • @KevinM.Mansour Sure, just change the 1000 to your preferred number – CertainPerformance May 31 '23 at 05:53
1

you can set value to one of the input and see if the value is changed

function trigger(){
  
  if(document.getElementById('isClicked').value ==0 ){
    console.log('clicked for the first time');
    document.getElementById('isClicked').value = 111;
    setTimeout(function(){
      document.getElementById('isClicked').value = 0;
    }, 1000);
  }
}
<button onclick='trigger()'>click me </button>
<input type='hidden' value=0 id='isClicked' />
noone
  • 6,168
  • 2
  • 42
  • 51
1

debounce the event to trigger in a certain period of time:

const element = document.querySelector('button');
let time;
element.addEventListener('click', (e) => {
  if (time) {
    clearTimeout(time);
  }

  time = setTimeout(() => console.log('runs after last click'), 500);
});
<button>Click!!!</button>
Jai
  • 74,255
  • 12
  • 74
  • 103
1

The most straightforward solution for this is to create a variable that acts as a gate that is reset after a certain time (one second in this example).

var el = document.querySelector('p');
var clickAllowed = true;

el.addEventListener('click', e => {
  if (!clickAllowed) {
    return;
  }
  clickAllowed = false;
  setTimeout(() => clickAllowed = true, 1000);

  // do stuff here
  console.log('test');
});
<p>Test</p>

On the first click, your code will run and the "gate" will close to stop a second click. After one second, the "gate" opens to allow the code to run again.

Adam
  • 3,829
  • 1
  • 21
  • 31
0

this code working for you

var el=document.getElementById('demo');
window.clicks=0;

// handle two click
el.addEventListener('click',function(){
 clicks++;
 el.innerHTML='clicks: '+clicks;
    setTimeout(function(){
     if (clicks == 1) {
         runYourCode();
         clicks=0;
        }
       else{
        clicks=0;
        return;
       }
 },400);
})

// dblclick event
el.addEventListener('dblclick',function(){
        runYourCode();
})


function runYourCode(){
 document.getElementById('text').innerHTML += '<br>Run your Code...';
};
#demo{
  background:red;
  padding:5px 10px;
  color:white;
  max-width:100px;
}
<p id="demo">click me!</p>

<p id="text">
log:<br>
</p>
MAjidH1
  • 121
  • 4