为什么我的倒数计时器不启动和停止?

Why won't my countdown timer start and stop?

我需要制作一个简单的从 5 到 0 的倒数计时器,并带有启动和停止计数器的按钮。我唯一不知道的是为什么我的计数器不会停止。

代码如下:

   function clock() {
     var myTimer = setInterval(myClock, 1000);
     var c = 5;

     function myClock() {
       document.getElementById("demo").innerHTML = --c;
       if (c == 0) {
         clearInterval(myTimer);
         alert("Reached zero");
       }
     }
   }
<p id="demo">5</p>
<button onclick="clock()">Start counter</button>
<button onclick="clearInterval(myTimer)">Stop counter</button>

myTimer 仅在函数范围内。一种解决方案是使其成为全球性的。

var myTimer;
function clock() {
     myTimer = setInterval(myClock, 1000);
     var c = 5;

     function myClock() {
       document.getElementById("demo").innerHTML = --c;
       if (c == 0) {
         clearInterval(myTimer);
         alert("Reached zero");
       }
     }
   }
<p id="demo">5</p>
<button onclick="clock()">Start counter</button>
<button onclick="clearInterval(myTimer)">Stop counter</button>

快速而肮脏的回答

   var myTimer;
   function clock() {
     myTimer = setInterval(myClock, 1000);
     var c = 5;

     function myClock() {
       document.getElementById("demo").innerHTML = --c;
       if (c == 0) {
         clearInterval(myTimer);
         alert("Reached zero");
       }
     }
   }
<p id="demo">5</p>
<button onclick="clock()">Start counter</button>
<button onclick="clearInterval(myTimer)">Stop counter</button>

timer 在你的函数中(因为它在你的函数内部声明,var)只能在你的函数内部访问。将 var 声明移到函数外部使其成为全局变量。

更好的解决方案

但是把东西放在全局范围内是(mostly) a bad idea。所以.....有更好的方法:

   
var myTimerObj = (function(document){
   
   var myTimer;

   function start() {
     myTimer = setInterval(myClock, 1000);
     var c = 5;

     function myClock() {
       document.getElementById("demo").innerHTML = --c;
       if (c == 0) {
         clearInterval(myTimer);
         alert("Reached zero");
       }
     }
   }
   
   function end() {
       clearInterval(myTimer)
   }

   return {start:start, end:end};
 })(document);
<p id="demo">5</p>
<button onclick="myTimerObj.start()">Start counter</button>
<button onclick="myTimerObj.end()">Stop counter</button>

更好的解决方案使用 revealing module pattern 并将 timer 保存在私有范围内,Tl;Dr 它会停止 timer污染全球范围。

好了,您只需要将 myTimer 设为全局即可。我还修复了重置计时器后不会显示 5 的故障。

var myTimer;
   function clock() {
     myTimer = setInterval(myClock, 1000);
     var c = 5;

     function myClock() {
       document.getElementById("demo").innerHTML = --c;
       if (c == 0) {
         clearInterval(myTimer);
         alert("Reached zero");
       }
     }
   }
<p id="demo">5</p>
<button onclick="clock(); document.getElementById('demo').innerHTML='5';">Start counter</button>
<button onclick="clearInterval(myTimer);">Stop counter</button>

这个解决方案在 React JS 中对我有用

let Timer =(function(){
    let timerObject;
    let callback=null;
    let seconds=0;
    let counter=()=>{
        seconds++;
        console.log("seconds",seconds);
        if (callback!==undefined) callback(seconds);
    }
    let setCallback=(_callback)=>{callback=_callback }
    let getSeconds=()=>{ return seconds;}
    let reset=()=>{ seconds=0;}
    let start=()=>{timerObject=setInterval(counter,1000);}
    let end=()=>{clearInterval(timerObject);}
    return {"start":start,"end":end, "getSeconds":getSeconds, "reset":reset,"setCallback":setCallback}; })();

export default Timer;