清除间隔不在所需点停止

clear interval not stopping at desired point

我查看了此站点上的其他一些类似问题,但无法解决此问题。下面是我正在制作的番茄时钟程序的一部分。问题是我无法在时钟到达 00:00 时停止此设置间隔方法。

这是我的代码:

var break_minutes = 0;
var ses_minutes = 0;
var ses_minutes_sec;
var display = document.querySelector('#time');

function increment_ses (id) {
    ses_minutes = ses_minutes + 1;
    document.getElementById("ses_value").innerHTML = ses_minutes ;
    document.getElementById("timmer_circle").innerHTML = ses_minutes;
}
function decrement_ses (id) {
    if (ses_minutes > 0) {
        ses_minutes = ses_minutes - 10;
    } if (ses_minutes < 0) {
        ses_minutes = 0;
    }
    document.getElementById("ses_value").innerHTML = ses_minutes ;
    document.getElementById("timmer_circle").innerHTML = ses_minutes;
}
function runTimer () {
    var minutes = ses_minutes-1;
    var seconds = 10;
    var interval = setInterval(function () {
        seconds = seconds -1;
        if (seconds == 0) {
            minutes --;
            seconds = 10 -1;
        } 
        function str_pad_left(string,pad,length) {
            return (new Array(length+1).join(pad)+string).slice(-length);
        }
        var finalTime = str_pad_left(minutes,'0',2)+':'+str_pad_left(seconds,'0',2);
        document.getElementById("timmer_circle").innerHTML= finalTime;
        if (minutes == 0) {
            if (seconds == 0) {
                return clearInterval(interval);
            }
        }
    },1000);
}

HTML

<html>
<head>
<title>Pomodoro</title>
<script src="pomodoro.js"></script>
</head>
<body>
    <style>
    .timmer_circle
    {
        width: 300px;
        height: 300px;
        border-radius: 50%;
        font-size: 50px;
        color: #fff;
        line-height: 300px;
        text-align: center;
        background: #000;
    }
    .break_length{width:100%;}
    #decrement{float:left;width:100px;}
    #break_value{text-align: center;padding-left: 100px;}
    #increment{margin:0 auto;width:100px;}

    .session_length{width:100%; margin-top: 10px;}
    #decrement_ses{float:left;width:100px;}
    #ses_value{padding-left: 100px;}
    #increment_ses{margin:0 auto;width:100px;}
    #start_but{margin-top: 20px;}
    #pause_but{margin-top: 20px; margin-left: 2px;}
    </style>
    <table>
        <tr>
            <td>
                <div class = "timmer_circle" id ="timmer_circle" value = ""> <span id = "time">Session</span> </div>
            </td>
        </tr>
    </table>
        <div class="session_length">
            <button type="button" id = "decrement_ses" onClick = "decrement_ses(this.id);">ses/dec</button>
            <button type="button" id = "ses_value" >0</button>
            <button type="button" id = "increment_ses" onClick = "increment_ses(this.id);">ses/inc</button>
        </div>

        <div class="break_length">
            <button type="button" id = "decrement" onClick = "decrement_break(this.id);">brk/dec</button>
            <button type="button" id = "break_value" value = "" >0</button>
            <button type="button" id = "increment" onClick = "increment_break(this.id);">brk/inc</button>    
        </div>
        <button id ="start_but" onClick="runTimer();">START</button>
        <button id ="pause_but">PAUSE</button>

</body>
</html>

所以,您的代码存在很多问题,特别是您计算秒和分钟的方式。当您按照自己的方式执行 case 语句时,秒数永远不会为零,因为您在函数开始时测试了零,然后将它们重置为 10-1。

我会将检查移到函数的开头,作为初始条件的一部分。还有其他问题,但这是为了回答您关于间隔的具体问题。以下代码将按预期退出:

var ses_minutes = 1;
var minutes = ses_minutes-1;
var seconds = 10;
var interval = setInterval(function () {
        seconds = seconds -1;
        if (seconds == 0) {
           if(minutes === 0){
              return clearInterval(interval);
           }
           minutes --;
           seconds = 10 - 1;
        } 
        function str_pad_left(string,pad,length) {
            return (new Array(length+1).join(pad)+string).slice(-length);
        }
        var finalTime = str_pad_left(minutes,'0',2)+':'+str_pad_left(seconds,'0',2);
        document.getElementById("timmer_circle").innerHTML= finalTime;
    },1000);

/* 编辑 */

所以花几分钟想想如果是我我会怎么做,我会把事情分解成稍微不同的函数,我也会使用 setTimeout。我还会根据经过的时间进行计算,而不是假设间隔或超时滴答将恰好发生在 1000 毫秒,因为这并不总是可靠的。下面的内容可能仍然不完美(我只做了粗略的测试)但更接近于我被分配到这个任务时我会做的事情:

const display = document.getElementById('timer');
const countDownFrom = 15000; // time in milliseconds to count from
let startTime = new Date().getTime();

function padNumber(num){
  let str = num.toString();
  return str.length > 1 ? str : '0' + str;
}

function getDisplay(milliseconds){
   const seconds = milliseconds / 1000;
   const displayMinutes = padNumber(Math.floor(seconds / 60));
   const displaySeconds = padNumber(Math.floor(seconds % 60));
   return displayMinutes + ':' + displaySeconds;
}

function tick(){
   const currentTime = new Date().getTime();
   const elapsedTime = currentTime - startTime;

   // test to see if the timer has expired
   if(countDownFrom - elapsedTime <= 0){ 
    display.innerHTML = '00:00';
    return;
   }

   display.innerHTML = getDisplay(countDownFrom - elapsedTime);
   setTimeout(tick,1000);
}

display.innerHTML = getDisplay(countDownFrom);
setTimeout(tick, 1000);