Home > Back-end >  way too keep function that called by event listener in execution
way too keep function that called by event listener in execution

Time:01-08

i try to make a button that get the time now ,put it in

element and updated every one second using the event listener the problem that the time disappear immediately

var time 
function updateTime(){
    time = new Date().toLocaleTimeString();
    document.getElementById('showtime').innerHTML=time
    setInterval(updateTime, 1000);
 }
 
 document.getElementById("btnclock").addEventListener("click", updateTime);


html 
<button id="btnclock"> Start Clock</button>
        <p id='showtime'> </p>

CodePudding user response:

Update can call setInterval(), but, as others have pointed out, we only want at most one interval timer running. This can be expressed tersely with a nullish coalescing assignment (not so tersely named).

Below, once the intervalID has been initialized, the setInterval() will no longer be evaluated. Keeping the interval id around is useful because it allows for a stop button, also demonstrated...

let intervalID;

function updateTime(run) {
  document.getElementById('showtime').innerHTML = (new Date()).toString()
  intervalID ??= setInterval(updateTime, 1000);
};

document
  .getElementById("btnclock")
  .addEventListener("click", updateTime);
  
document
  .getElementById("btnclock-stop")
  .addEventListener("click", () => {
    clearInterval(intervalID)
    intervalID = null;  // so the setInterval assignment can run
  });
<button id="btnclock"> Start</button>
<p id='showtime'>&nbsp</p>
<br/>
<button id="btnclock-stop"> Stop</button>

CodePudding user response:

The issue is that when you click the button, updateTime function calls setInterval(updateTime, 1000) which creates a timer. The timer calls updateTime function every second. But updateTime creates another timer while the first one is still running. So in fact what is happening is that every second every running timer creates a new timer so after 10 seconds you will have 1024 timers running at the same time. This is obviously not what you want.

Try something like this:

var timer = 0;

function startTimer() {
  if (!timer) {
    timer = setInterval(updateTime, 1000);
  }
}

function stopTimer() {
  clearInterval(timer);
  timer = 0;
}

function updateTime() {
  var time = new Date().toLocaleTimeString();
  document.getElementById("show-time").innerHTML = time;
}

document.getElementById("start-clock").addEventListener("click", startTimer);
document.getElementById("stop-clock").addEventListener("click", stopTimer);
<button id="start-clock">Start Clock</button>
<button id="stop-clock">Stop Clock</button>
<p id="show-time"></p>

It is important to destroy the timer when you no longer need it. Function clearInterval does it.

  • Related