为什么在按钮单击时Javascript clearInterval不起作用?

时间:2020-09-26 04:01:06

标签: javascript

我有一个计时器程序,该程序从“开始”按钮单击时的25:00开始倒计时,应该重置,而在“重置”按钮单击时clearInterval()倒计时。当计时器到0:00时,所有if语句都会通过,并且调用resetTimer()并执行在此实例中起作用的clearInterval()。简而言之:clearInterval()在if语句通过时有效,但在我单击“重置”按钮时无效。有人可以向我解释为什么会这样并提供解决方案吗?谢谢!

//My Programs Code:
//Timer Widget
function timerStartReset(event) {
  var minutes;
  var seconds;

  //decrease minutes html every minute
  const minutesInterval = setInterval(() => {
    minutes -= 1;
    timerMinute.innerHTML = minutes;
  }, 60000);

  //decrease seconds html every second
  const secondsInterval = setInterval(() => {
    seconds -= 1;
    timerSeconds.innerHTML = seconds < 10 ? `0${seconds}` : seconds;
    //check if timer reaches 00:00
    if (seconds <= 0) {
      if (minutes <= 0) {
        //stop and reset timer

        //**HERE resetTimer() is called and clearInterval works**

        resetTimer();
        //return start button functionality
        timerStartBtn.disabled = false;
        //add a star
        const addStar = `<i class="fas fa-star h2 mx-2"></i>`;
        timerStarContainer.insertAdjacentHTML("beforeend", addStar);
        localStorage.setItem("timer stars", timerStarContainer.innerHTML);
        setTimeout(breakAlert, 1000);
      }
      seconds = 60;
    }
  }, 1000);

  //start button function
  if (event.target.id === "timer-start") {
    startTimer();
    event.target.disabled = true;
  }
  //reset button function
  else {

    //**HERE resetTimer() is called but clearInterval doesn't work**

    resetTimer();
    timerStartBtn.disabled = false;
  }

  //Reset timer
  function resetTimer() {
    //Reset to starting template
    timerMinute.innerHTML = 25;
    timerSeconds.innerHTML = "00";
    //Clear minute/second timeout function
    clearInterval(minutesInterval);
    clearInterval(secondsInterval);
  }

  //start timer
  function startTimer() {
    //Change starting time and add them to page
    minutes = 0;
    seconds = 1;

    timerMinute.innerHTML = minutes;
    timerSeconds.innerHTML = seconds;

    //start countdown
    minutesInterval;
    secondsInterval;
  }

  //Alert for breaks
  function breakAlert() {
    //If 4 star divs are added dynamically
    if (timerStarContainer.childElementCount >= 4) {
      swal(
        "Great Job! You Did It!",
        "Go ahead and take a 15-30 minute break!",
        "success"
      );
      //remove all stars from DOM
      timerStarContainer.innerHTML = "";
    } else {
      swal("Awesome!", "Please take a 5 minute break!", "success");
    }
  }
}
//End Timer Widget 

const timerMinute = document.querySelector("#minute");
const timerSeconds = document.querySelector("#seconds");
const timerStartBtn = document.querySelector("#timer-start");
document.querySelector("#timer-btns").addEventListener("click", timerStartReset);

//Timer Widget
function timerStartReset(event) {
  var minutes;
  var seconds;

  //decrease minutes html every minute
  const minutesInterval = setInterval(() => {
    minutes -= 1;
    timerMinute.innerHTML = minutes;
  }, 60000);

  //decrease seconds html every second
  const secondsInterval = setInterval(() => {
    seconds -= 1;
    timerSeconds.innerHTML = seconds < 10 ? `0${seconds}` : seconds;
    //check if timer reaches 00:00
    if (seconds <= 0) {
      if (minutes <= 0) {
        //stop and reset timer
        resetTimer();
        //return start button functionality
        timerStartBtn.disabled = false;
      }
      seconds = 60;
    }
  }, 1000);

  //start button function
  if (event.target.id === "timer-start") {
    startTimer();
    event.target.disabled = true;
  }
  //reset button function
  else {
    resetTimer();
    timerStartBtn.disabled = false;
  }

  //Reset timer
  function resetTimer() {
    //Reset to starting template
    timerMinute.innerHTML = 0;
    timerSeconds.innerHTML = 11;
    //Clear minute/second timeout function
    clearInterval(minutesInterval);
    clearInterval(secondsInterval);
    console.log("reset");
  }

  //start timer
  function startTimer() {
    //Change starting time and add them to page
    minutes = 0;
    seconds = 10;

    timerMinute.innerHTML = minutes;
    timerSeconds.innerHTML = seconds;

    //start countdown
    minutesInterval;
    secondsInterval;
  }
}
//End Timer Widget
<!-- Timer -->
    <div>
      <span id="minute">0</span>
      <span>:</span>
      <span id="seconds">11</span>
    </div>
    
    <div id="timer-btns">
      <button id="timer-start">Start</button>
      <button id="timer-reset">Reset</button>
    </div>
<!-- End Timer -->

1 个答案:

答案 0 :(得分:1)

变量minutesIntervalsecondsInterval在此函数中是局部的。因此,每次调用该函数时,它都会启动新的计时器并创建新的变量。当代码调用resetTimer()时,仅重置由timerStartReset的调用而启动的计时器,而不是先前的计时器。

它在计时器用尽时起作用,因为倒计时代码在同一范围内。但是,当您单击“重置”按钮时,该功能是一个新作用域,并且从单击“开始”按钮后就无法访问变量。

计时器变量应该是可以从任何调用中访问的全局变量。这样就没有理由对两个按钮使用相同的功能。

var minutesInterval;
var secondsInterval;

timerStartBtn.addEventListener('click', timerStart);
timerResetBtn.addEventListener('click', resetTimer);

function timerStart() {
  resetTimer();

  var minutes;
  var seconds;

  //decrease minutes html every minute
  minutesInterval = setInterval(() => {
    minutes -= 1;
    timerMinute.innerHTML = minutes;
  }, 60000);

  //decrease seconds html every second
  secondsInterval = setInterval(() => {
    seconds -= 1;
    timerSeconds.innerHTML = seconds < 10 ? `0${seconds}` : seconds;
    //check if timer reaches 00:00
    if (seconds <= 0) {
      if (minutes <= 0) {
        resetTimer();
        //return start button functionality
        timerStartBtn.disabled = false;
        //add a star
        const addStar = `<i class="fas fa-star h2 mx-2"></i>`;
        timerStarContainer.insertAdjacentHTML("beforeend", addStar);
        localStorage.setItem("timer stars", timerStarContainer.innerHTML);
        setTimeout(breakAlert, 1000);
      }
      seconds = 60;
    }
  }, 1000);

  startTimer();

  //start timer
  function startTimer() {
    //Change starting time and add them to page
    minutes = 0;
    seconds = 1;

    timerMinute.innerHTML = minutes;
    timerSeconds.innerHTML = seconds;

    //start countdown
    minutesInterval;
    secondsInterval;
  }

  //Alert for breaks
  function breakAlert() {
    //If 4 star divs are added dynamically
    if (timerStarContainer.childElementCount >= 4) {
      swal(
        "Great Job! You Did It!",
        "Go ahead and take a 15-30 minute break!",
        "success"
      );
      //remove all stars from DOM
      timerStarContainer.innerHTML = "";
    } else {
      swal("Awesome!", "Please take a 5 minute break!", "success");
    }
  }
}

//Reset timer
function resetTimer() {
  //Reset to starting template
  timerMinute.innerHTML = 25;
  timerSeconds.innerHTML = "00";
  //Clear minute/second timeout function
  clearInterval(minutesInterval);
  clearInterval(secondsInterval);
}

//End Timer Widget