简体   繁体   中英

How to properly use clearInterval

I want this reset button to clear/reset the timer. I need it to reset because when the user presses the start button more then once it set´s two timers one that was started previously and the one that was just started.

I´m going to use clearInterval to fix this.

Here is my timer:

 function startTimer(duration, display) { var timer = duration, minutes, seconds; setInterval(function () { minutes = parseInt(timer / 60, 10); seconds = parseInt(timer % 60, 10); minutes = minutes < 10 ? "0" + minutes : minutes; seconds = seconds < 10 ? "0" + seconds : seconds; display.textContent = minutes + ":" + seconds; if (--timer < 0) { timer = duration; } function resetTimer(){ clearInterval(timer); } }, 1000); } function start5Timer() { var fiveMinutes = 60 * 5, display = document.querySelector('#time'); startTimer(fiveMinutes, display); };
 <body> <div><span id="time">05:00</span> minutes! <button onclick="start5Timer()">start</button> <button onclick="resetTimer()">reset</button> </div> </body>

You can use timerId in the global scope. Set it's value when the interval starts and use the timerId to clear the interval and start a new timer starting from 05:00

<html>

  <body>
    <div><span id="time">05:00</span> minutes!
      <button onclick="start5Timer()">start</button>
      <button onclick="resetTimer()">reset</button>
    </div>
  </body>

  <script>
    let timerId;
    function startTimer(duration, display) {
      var timer = duration,
        minutes, seconds;
      timerId = setInterval(function() {
        minutes = parseInt(timer / 60, 10);
        seconds = parseInt(timer % 60, 10);

        minutes = minutes < 10 ? "0" + minutes : minutes;
        seconds = seconds < 10 ? "0" + seconds : seconds;

        display.textContent = minutes + ":" + seconds;

        if (--timer < 0) {
          timer = duration;
        }
      }, 1000);
    }
    
     function resetTimer() {
          clearInterval(timerId);
          start5Timer();
        }

    function start5Timer() {
      var fiveMinutes = 60 * 5,
      display = document.querySelector('#time');
       startTimer(fiveMinutes, display);
    };

  </script>

</html>

Here's a timer implementation using unidirectional data-flow and immutable state.

There are three actions: start, reset and tick. When dispatched to the store, the state is updated.

The timer controls its own rendering using requestAnimationFrame .

 function createStore(initialState, reducers) { let state = Object.freeze(initialState) const reducerMap = reducers.reduce( (p, { type, reducer }) => (p[type] ? p[type].push(reducer) : (p[type] = [reducer]), p), {}) function dispatch(action, ...args) { state = reducerMap[action].reduce((p, c) => c(p, ...args), state) } return { dispatch, getState() { return state } } } const toTwoDigitString = (n) => (n + "").padStart(2, "0") const formatForDisplay = (seconds) => `${toTwoDigitString(~~(seconds / 60))}:${toTwoDigitString( ~~(seconds % 60) )} minutes` const tick = (store) => store.getState().elapsedSeconds >= store.getState().durationSeconds ? clearInterval(store.getState().timerId) : store.dispatch(ACTION_TICK) const startTimer = (store) => { if (store.getState().timerId !== null) return const timerId = setInterval(() => tick(store), 1000) store.dispatch(ACTION_START, timerId) } const resetTimer = (store) => { clearInterval(store.getState().timerId) store.dispatch(ACTION_RESET) } const render = ({ displayEl, durationSeconds, elapsedSeconds }) => (displayEl.innerHTML = formatForDisplay(durationSeconds - elapsedSeconds)) const ACTION_START = "ACTION_START" const ACTION_RESET = "ACTION_RESET" const ACTION_TICK = "ACTION_TICK" const reducerStart = { type: ACTION_START, reducer(state, timerId) { return { ...state, timerId } } } const reducerReset = { type: ACTION_RESET, reducer(state) { return { ...state, timerId: null, elapsedSeconds: 0 } } } const reducerTick = { type: ACTION_TICK, reducer: (state) => { return { ...state, elapsedSeconds: ++state.elapsedSeconds } } } function createTimer({ selector, durationSeconds }) { const timerEl = document.querySelector(selector) const initialState = { timerId: null, displayEl: timerEl.querySelector("#time"), durationSeconds, elapsedSeconds: 0 } const store = createStore(initialState, [ reducerStart, reducerReset, reducerTick ]) const start = () => startTimer(store) const reset = () => resetTimer(store) timerEl.querySelector("button#start").addEventListener("click", start) timerEl.querySelector("button#reset").addEventListener("click", reset) const previousState = null ;(function renderLoop() { if (previousState !== store.getState()) render(store.getState()) requestAnimationFrame(renderLoop) })() } createTimer({ selector: "#timer", durationSeconds: 2 * 5 })
 * { font-family: sans-serif; color: #dc1a1a !important; font-size: 1.1rem; padding: 10px; margin: 10px; }
 <div id="timer"> <span id="time">The time is:</span> <button id="start">start</button> <button id="reset">reset</button> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM