Search code examples
javascripttimermouseover

Javascript mouseover run function, then wait and run again


I am trying to get a function to fire on mouseover of an element. However, if the function is already running I want it to not fire.

I have this for the mouseover trigger

onmouseover="runFunc()">

and I have this for the js:

var timerStarted = false;

function waitToStart() {
  timerStarted = false;
}


function runFunc() {

  if (!timerStarted) {

     console.log('run function');
   } 

   timerStarted = true;
   setTimeout(waitToStart, 6000);
}

When I first hover over the element, I get

run function

and nothing happens for 6 seconds which seemed like it was working. However after 6 seconds the console output counted fast up to the amount of times I hovered over the function:

(24) run function

I'm struggling to understand why and how to make sure that the function only fires every 6 seconds after mouseover.


Solution

  • You're starting many timers. And eventually they all end and each set your boolean to false, even when in the half second before that you still started yet another timer.

    What you really want is to either cancel any previously launched timer before issuing a new one, or to only launch a new one when you are sure the preceding one already timed out. The effect is a bit different: the first solution will reset the countdown with every mousemove (so must hold it still for at least 6 seconds), while the second will just make sure that there are at least 6 seconds between executions of the if block.

    Here is how the second approach works:

    var timerStarted = false;
    
    function waitToStart() {
      timerStarted = false;
    }
    
    function runFunc() {
       if (!timerStarted) {
          console.log('run function');
          timerStarted = true;           // <--- moved inside the IF block
          setTimeout(waitToStart, 6000); //
       } 
    }