【问题标题】:Stop watch java script without using Date.getTime()不使用 Date.getTime() 的秒表 javascript
【发布时间】:2014-05-30 03:37:57
【问题描述】:

作为一个 java 脚本初学者,我想尝试编写秒表代码,我写了以下代码:

<!DOCTYPE html>
<html>
<body>
    <p>A script on this page starts a stopwatch:</p>
    <p id="demo"></p>

    <button id="start-stop" onclick="myTimerFunction()">Start time</button>
    <button id="resetter" style="visibility:hidden" onclick="resetTimer()">Reset</button>

    <script>
        var timer = new Object();
        timer.hours = 0;
        timer.minutes = 0;
        timer.seconds = 0;
        timer.milliseconds = 0;
        timer.add = add;
        function add() {
            timer.milliseconds+=10;
            if(timer.milliseconds == 1000) {
                timer.seconds++;
                timer.milliseconds = 0;
            }
            if(timer.seconds == 60) {
                timer.minutes++;
                timer.seconds = 0;
            }
            if(timer.minutes == 60) {
                timer.hours++;
                timer.minutes = 0;
            }
        }
        timer.display = display;
        function display () {
            var str = "";
            if(timer.hours<10) {
                str += "0";
            }
            str += timer.hours;
            str += ":";
            if(timer.minutes<10) {
                str += "0";
            }
            str += timer.minutes;
            str += ":";
            if(timer.seconds<10) {
                str += "0";
            }
            str += timer.seconds;
            str += ":";
            /*var x = timer.milliseconds/10;
            if(x < 10) {
                str += "0";
            }*/
            if(timer.milliseconds<10) {
                str += "0";
            }
            if(timer.milliseconds<100) {
                str += "0";
            }
            str += timer.milliseconds;
            return str;
        }
        timer.reset = reset;
        function reset() {
            timer.hours = 0;
            timer.minutes = 0;
            timer.seconds = 0;
            timer.milliseconds = 0;
        }

        var myVar;
        function start() {
            timer.add();
            var d = new Date();
            var t = d.toLocaleTimeString();
            document.getElementById("demo").innerHTML = timer.display() + "\t" + t;
        }

        function stop() {
            clearInterval(myVar);
        }

        function resetTimer() {
            stop();
            timer.reset();
            document.getElementById("demo").innerHTML = timer.display();
            document.getElementById("start-stop").innerHTML="Start time";
            document.getElementById("resetter").style.visibility="hidden";
        }

        function myTimerFunction() {
            var x = document.getElementById("start-stop");
            if(x.innerHTML.match("Start time")) {
                document.getElementById("resetter").style.visibility="visible";
                myVar = setInterval(function(){start()},10);
                x.innerHTML="Stop time";
            }
            else if(x.innerHTML.match("Stop time")) {
                stop();
                x.innerHTML="Start time";
            }
        }
    </script>
</body>
</html>

但是,问题是当我将 delay 放入 setInterval(func,delay) 为 1 并进行相应的更改,它没有给出可靠的秒数。它比普通时钟慢。它为 delay >= 10 提供了“某种”可靠的时间。

我在网上检查了秒表 js 脚本,但它们都使用某种或其他形式的 Date() 并将“延迟”设置为“50”,到目前为止我不明白为什么。 SO中有一个不使用 Date() 的答案,但它也有与我相同的问题。由于我没有足够的声誉,我无法在那里发表评论,所以我提出了一个问题。

所以,我的问题是:如果我们不使用 Date() 函数,是否不可能实现正常的时钟可靠性?否则,如果可能,请帮助我改进这段代码或提供一些指导。

谢谢。

【问题讨论】:

  • 你想避免getTime,因为?
  • 我觉得我依赖于一个已经可用的计数器。由于我正在实施一个计数器,我觉得这不是我应该选择的,而是其他方式。但是,现在我觉得我正在重新实现轮子。
  • 我在下面的回答提供了一个示例,说明您在单击 Fiddle 时正在尝试什么。 getTime 对于更长的持续时间更合适/更准确。
  • 是的,看起来是这样。我应该做更多的研究。感谢您的投入:)

标签: javascript stopwatch


【解决方案1】:

您已经发现setInterval/setTimeout 不可靠。您必须使用本地时间库来获得可靠的时间。

由于您无法在 JavaScript 中保持时间,因此您的想法是轮询时间,并经常轮询它,以使其看起来足够接近。

如果你天真地这样做:

setInterval(function () {
    console.log((new Date()).getTime();
}, 1000); // 1 second

你会看到它会跳过几秒钟。

更好的方法是:

var last = 0;
setInterval(function () {
    var now = Math.floor((new Date()).getTime() / 1000); // now in seconds
    if (now !== last) {
        console.log(now);
        last = now;
    }
}, 10); // 10ms

【讨论】:

  • 你为什么要每 10 毫秒 Math.floor 秒?
  • 我想你可以改用if (last &gt;= now - 1) {。这可能会更好。
  • @Doge 我认为应该是 if (last &lt;= now - 1),因为 last0now 是一个很大的数字。
【解决方案2】:

如果您还想了解 JavaScript 计时器为何不可靠的更多信息,请阅读这篇精彩的文章。

http://ejohn.org/blog/how-javascript-timers-work/

【讨论】:

  • 谢谢,读得很好。现在,我明白我不应该过多依赖 setInterval 的“延迟”,而是应该给它足够的时间来恢复。
【解决方案3】:

如果没有getTime,你会这样做,你真的不应该这样做......

var ms = 0;
var intervalID;

function start() {
    var freq = 10; // ms
    intervalID = setInterval(function () {
        ms += 10;
        var myDate = new Date(ms);
        document.getElementById('watch').innerHTML = myDate.getUTCHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds() +
            ":" + myDate.getMilliseconds();
    }, freq);
}

function stop() {
    clearInterval(intervalID);
}

function reset() {
    ms = 0;
    myDate = new Date(ms);
    document.getElementById('watch').innerHTML = myDate.getUTCHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds() +
        ":" + myDate.getMilliseconds();
}

Fiddle

【讨论】:

    猜你喜欢
    • 2011-12-29
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 2015-08-22
    相关资源
    最近更新 更多