-1

I am trying to prevent users from running a function two consecutive times due to a double click. In the code below, I have the click event attached to the image and when the onclick function is called, the first thing i do is remove the click event. Once the function is done, I replace the click event. This works as it should when single clicking, but when double clicking the function gets called twice. Even if the second click comes after the message is logged to the console, it still fires twice. Is there any way to prevent this?

<div id="pre">
   <img src="/pics/magnifying_glass_lg.png" id='preloader' onmouseover='style.setProperty("cursor","pointer");' onclick='start_search(this)';>
</div>

function start_search(button){
    button.onclick=function(){};
    console.log("click is removed");
   // stuff goes here
   var el = document.getElementById('preloader');
   el.onclick=function(){start_search(el)};
}
John
  • 1,310
  • 3
  • 32
  • 58
  • 2
    Usually what people do is start a timer on the first click that runs for an appropriate interval and ignore clicks before the timer expires. – Pointy Aug 09 '23 at 15:48
  • 4
    "Debouncing" is a solved problem, so look for that term. – tadman Aug 09 '23 at 15:48
  • 1
    Does this answer your question? [Debounce function in jQuery](https://stackoverflow.com/questions/27787768/debounce-function-in-jquery) – evolutionxbox Aug 09 '23 at 16:03
  • Trying the debounce function still registers a second click. – John Aug 09 '23 at 18:36

1 Answers1

0

The problem was that javascript executes the line:

el.onclick=function(){start_search(el)};

immediately without waiting for the code above it to complete. So the onclick event was reinstated fast enough to register the second click. The only way to make it wait for the code above it was to put it in a timer. However, I thought the timer needed to be long enough for the code above it to finish, but that is not correct. Since I didn't know how long the code above it was going to take to execute I would have had to put an (unnecessarily) long delay on the timer. But that is not how it works. It simply needs a timer of basically any length to cause the execution of the line to wait for the previous code in the function to be executed before it gets executed. So the delay is only 10ms but yet it takes a few seconds before the button is clickable again because of the code in the function.

So the last line now looks like:

setTimeout(function() {el.onclick = function(){el.onclick = null; start_search(el)};},10);

so the second click (and any subsequent clicks) are ignored during the execution of the function. Once the function is complete the button becomes clickable again.

John
  • 1,310
  • 3
  • 32
  • 58