如何暂停和恢复 JavaScript 计时器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16134997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:23:20  来源:igfitidea点击:

How to pause and resume a javascript timer

javascripttimerresume

提问by user2303981

I have this timer which works fine, but i need to be able to pause and resume it after that. i would appreciate it if someone could help me.

我有一个可以正常工作的计时器,但我需要能够在此之后暂停和恢复它。如果有人可以帮助我,我将不胜感激。

<html>
<head>
<script>
function startTimer(m,s)
    {
        document.getElementById('timer').innerHTML= m+":"+s;
        if (s==0)
            {
               if (m == 0)
                {
                    return;
                }
                else if (m != 0)
                {
                    m = m-1;
                    s = 60;
                }
        }
    s = s-1;
    t=setTimeout(function(){startTimer(m,s)},1000);
}


</script>
</head>

<body>
<button onClick = "startTimer(5,0)">Start</button>

<p id = "timer">00:00</p>
</body>
</html>

回答by Niet the Dark Absol

I simply can't stand to see setTimeout(...,1000)and expecting it to be exactly 1,000 milliseconds. Newsflash: it's not. In fact, depending on your system it could be anywhere between 992 and 1008, and that difference will add up.

我简直无法忍受看到setTimeout(...,1000)并期望它正好是 1,000 毫秒。快讯:不是。事实上,根据您的系统,它可能介于 992 和 1008 之间,而且这种差异会加起来。

I'm going to show you a pausable timer with delta timing to ensure accuracy. The only way for this to not be accurate is if you change your computer's clock in the middle of it.

我将向您展示一个带有增量计时的可暂停计时器,以确保准确性。唯一不准确的方法是您在中间更改计算机的时钟。

function startTimer(seconds, container, oncomplete) {
    var startTime, timer, obj, ms = seconds*1000,
        display = document.getElementById(container);
    obj = {};
    obj.resume = function() {
        startTime = new Date().getTime();
        timer = setInterval(obj.step,250); // adjust this number to affect granularity
                            // lower numbers are more accurate, but more CPU-expensive
    };
    obj.pause = function() {
        ms = obj.step();
        clearInterval(timer);
    };
    obj.step = function() {
        var now = Math.max(0,ms-(new Date().getTime()-startTime)),
            m = Math.floor(now/60000), s = Math.floor(now/1000)%60;
        s = (s < 10 ? "0" : "")+s;
        display.innerHTML = m+":"+s;
        if( now == 0) {
            clearInterval(timer);
            obj.resume = function() {};
            if( oncomplete) oncomplete();
        }
        return now;
    };
    obj.resume();
    return obj;
}

And use this to start/pause/resume:

并使用它来启动/暂停/恢复:

// start:
var timer = startTimer(5*60, "timer", function() {alert("Done!");});
// pause:
timer.pause();
// resume:
timer.resume();

回答by Xotic750

<p id="timer">00:00</p>
<button id="start">Start</button>
<button id="pause">Pause</button>
<button id="resume">Resume</button>

var timer = document.getElementById("timer");
var start = document.getElementById("start");
var pause = document.getElementById("pause");
var resume = document.getElementById("resume");
var id;
var value = "00:00";

function startTimer(m, s) {
    timer.textContent = m + ":" + s;
    if (s == 0) {
        if (m == 0) {
            return;
        } else if (m != 0) {
            m = m - 1;
            s = 60;
        }
    }

    s = s - 1;
    id = setTimeout(function () {
        startTimer(m, s)
    }, 1000);
}

function pauseTimer() {
    value = timer.textContent;
    clearTimeout(id);
}

function resumeTimer() {
    var t = value.split(":");

    startTimer(parseInt(t[0], 10), parseInt(t[1], 10));
}

start.addEventListener("click", function () {
    startTimer(5, 0);
}, false);

pause.addEventListener("click", pauseTimer, false);

resume.addEventListener("click", resumeTimer, false);

on jsfiddle

jsfiddle 上

There are a whole load of improvements that could be made but I'm sticking with the code that the OP posted for the OP's comprehension.

可以进行大量改进,但我坚持使用 OP 为 OP 的理解发布的代码。

Here is an extended version to give you further ideas on jsfiddle

这是一个扩展版本,可为您提供有关jsfiddle 的更多想法