javascript 以毫秒为单位的 JQuery 倒数计时器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22385368/
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 23:02:45  来源:igfitidea点击:

JQuery countdown timer with milliseconds

javascriptjquery

提问by StevenPHP

I have a very basic lightweight function that counts down from 30 seconds. I have been trying to add milliseconds to it but I can't seem to get it to work correctly.

我有一个非常基本的轻量级函数,从 30 秒开始倒计时。我一直在尝试为其添加毫秒,但似乎无法正常工作。

var count = 30;
var counter = setInterval(timer, 1000); //1000 will  run it every 1 second

function timer() {
    if (count <= 0) {
        clearInterval(counter);
        return;
    }
    count = count - 1;
    document.getElementById("timer").innerHTML = count + " secs"; // watch for spelling
}

回答by MirroredFate

Try it this way. Stopwatches only count hundredths of seconds anyway.

试试这个方法。无论如何,秒表只能计算百分之一秒。

var count = 3000;

var counter = setInterval(timer, 10); //10 will  run it every 100th of a second

function timer()
{
    if (count <= 0)
    {
        clearInterval(counter);
        return;
     }
     count--;
     document.getElementById("timer").innerHTML=count /100+ " secs"; 
}

Just for better formatting and testing:

只是为了更好的格式化和测试

HTML

HTML

<span id="timer"></span>

<button id="start">start</button>
<button id="stop">stop</button>
<button id="reset">reset</button>

Javascript

Javascript

var initial = 30000;
var count = initial;
var counter; //10 will  run it every 100th of a second

function timer() {
    if (count <= 0) {
        clearInterval(counter);
        return;
    }
    count--;
    displayCount(count);
}

function displayCount(count) {
    var res = count / 100;
    document.getElementById("timer").innerHTML = res.toPrecision(count.toString().length) + " secs";
}

$('#start').on('click', function () {
    clearInterval(counter);
    counter = setInterval(timer, 10);
});

$('#stop').on('click', function () {
    clearInterval(counter);
});

$('#reset').on('click', function () {
    clearInterval(counter);
    count = initial;
    displayCount(count);
});

displayCount(initial);

EDIT:

编辑:

The original question was trying to figure out how to make a display like a stopwatch, and I know very few that actually count milliseconds. That being said, hereis a possible solution to do that. It relies on updating as fast as possible, and getting the difference between our last update and our current one to remain accurate.

最初的问题是试图弄清楚如何制作像秒表一样的显示,我知道很少有真正计算毫秒的。话虽如此,是一个可能的解决方案。它依赖于尽可能快的更新,并让我们上次更新和当前更新之间的差异保持准确。

var initial = 300000;
var count = initial;
var counter; //10 will  run it every 100th of a second
var initialMillis;

function timer() {
    if (count <= 0) {
        clearInterval(counter);
        return;
    }
    var current = Date.now();

    count = count - (current - initialMillis);
    initialMillis = current;
    displayCount(count);
}

function displayCount(count) {
    var res = count / 1000;
    document.getElementById("timer").innerHTML = res.toPrecision(count.toString().length) + " secs";
}

$('#start').on('click', function () {
    clearInterval(counter);
    initialMillis = Date.now();
    counter = setInterval(timer, 1);
});

$('#stop').on('click', function () {
    clearInterval(counter);
});

$('#reset').on('click', function () {
    clearInterval(counter);
    count = initial;
    displayCount(count);
});

displayCount(initial);

回答by Ian Clark

The problem is that the browser can't possibly handle manipulating the DOMevery millisecond. For this reason, lots of browsers actually set a minimum value for intervals - and the W3C suggest a minimum of 4ms (source). We can use this information to create a throttledapproachwhich runs as quickly as possible.

问题是浏览器不可能每毫秒处理一次DOM 操作。出于这个原因,许多浏览器实际上设置了间隔的最小值 - W3C 建议至少 4ms (source)。我们可以使用此信息来创建尽可能快地运行的节流方法

// We actually only run our method every x millisecs, due to browser constraints
var THROTTLE_AMOUNT = 4;

countdown(30);

function countdown(secs) {
    var milli = secs * (1000);
    var counter = setInterval(function() {
        if(milli <= 0) {
            clearInterval(counter);
            return
        }
        milli -= THROTTLE_AMOUNT;
        document.getElementById("timer").innerHTML = milli + " millisecs"; // watch for spelling
    }, THROTTLE_AMOUNT);
}

回答by Oscar Paz

You can try this. If you're targeting modern browsers, you may have access to the PerformanceAPI, which gives high resolution timestamps instead of normal timestamps.

你可以试试这个。如果您的目标是现代浏览器,您可能可以访问PerformanceAPI,它提供高分辨率时间戳而不是普通时间戳。

An improved solution would use requestAnimationFrame(). Updating the DOM every millisecond, even if possible with setTimeout(), is a waste of resources, as the browser will only refresh the screen, typically, 60 times in a second (every 16.6 ms). Updating the clock two times or more in that interval would be useless, and the user will only see the last value.

改进的解决方案将使用requestAnimationFrame(). 每毫秒更新一次 DOM,即使可能使用 setTimeout(),也是一种资源浪费,因为浏览器只会刷新屏幕,通常每秒 60 次(每 16.6 毫秒)。在该时间间隔内更新时钟两次或更多次是没有用的,用户只会看到最后一个值。

function now() {
    return window.performance ? window.performance.now() : Date.now();
}

var count = 30000;
var delay = 20; //20 ms. This will be only indicative. There's no guarantee the browswer will call the function after exactly this time

var initTick = 0;
var timerElement = document.getElementById("timer");
function tick() {
   var remaining = (count - (now() - initTick)) / 1000;  
   console.log(remaining);
   remaining = remaining >= 0 ? remaining : 0;
   var secs = remaining.toFixed(2);
   timerElement.innerHTML = secs + " secs";
   if (remaining) setTimeout(tick, delay);
}

initTick = now();
console.log(now());
setTimeout(tick, delay);

JSFIDDLE.

JSFIDDLE。

回答by Naveen Chandra Tiwari

  This may help you:

    var count = 30;
    var count1 = 60;
        //1000 will  run it every 1 second
        var counter1;
        var counter = setInterval(timer, 1000);

        function timer1() {
            if (count1 <= 0 && count < 1) {
                clearInterval(counter1);
                return;
            } else {
                if (count1 <= 0 && count > 0)
                    count1 = 60;
                else
                    count1 = count1 - 1;
                //var counter=setInterval(timer, 1000);
            }
            document.getElementById("timer").innerHTML = count + "." + count1 + " secs"; // watch for spelling
        }
        function timer() {
            if (count <= 0) {
                clearInterval(counter);
                return;
            }
            else {
                counter1 = setInterval(timer1, 10);
            }
            count = count - 1;

        }

回答by denodster

Based on Previous responses, I've derived a vanilla javascript, object oriented approach.

基于以前的回复,我推导出了一个 vanilla javascript,面向对象的方法。

I've also created a github repo in case anyone wants to improve it.

我还创建了一个 github repo,以防有人想改进它。

https://github.com/denodster/JSTimer

https://github.com/denodster/JSTimer

function Timer(element){
    var interval;
    var milliseconds = 0;
    var self = this;

    function printValue(){
        var seconds = Math.round(milliseconds/10)/100;
        $(element).empty();
        $(element).text(seconds);
    }

    this.start = function(seconds, countdown){
        if(interval){//if an interval exists clear it first
            clearInterval(interval);
        }
        if(seconds) {//if seconds are passed in reset the milliseconds
            milliseconds = milliseconds + (seconds * 1000);
        }
        interval = setInterval(function(){
            if(countdown) {
                if (milliseconds >= 0) {
                    milliseconds -= 10;
                    printValue();
                } else {
                    self.stop();
                }
            } else {
                milliseconds += 10;
                printValue();
            }
        }, 10);
    };

    this.stop = function(){
        clearInterval(interval);
    };

    this.reset = function(){
        milliseconds = 0;
        printValue();
    };

    this.getValue = function(){
        return milliseconds/1000;
    };
}

Example:

例子:

<span id="counter"></span>
<script type="text/javascript">
//count down to zero from 10 seconds
var counter = document.getElementById('counter');
var timer = new Timer(counter);
timer.start(10, true);
</script>

回答by BannerBomb

I know this post is old but I thought I should share my answer maybe it will help someone. This script counts the current date/time with milliseconds, minutes, seconds, month, day, year, and suffix, it is easy to modify, you can modify it to countdown if you need to

我知道这篇文章很旧,但我想我应该分享我的答案,也许它会对某人有所帮助。本脚本以毫秒、分、秒、月、日、年、后缀统计当前日期/时间,修改方便,如果需要可以修改为倒计时

    function showRemaining() {
    var currentDate = new Date(); //'11/23/2016 12:00 AM'
    var month = currentDate.getMonth() + 1
    var day = currentDate.getDate()
    var year = currentDate.getFullYear()
    var currentTime = new Date()
    var hours = currentTime.getHours()
    var minutes = currentTime.getMinutes();
    var seconds = currentTime.getSeconds();
    //var milliseconds = currentTime.getMilliseconds().toString().slice(0, 3); //+ 999; //* 111
    var milliseconds = (currentTime.getMilliseconds()/.11).toFixed(0)
    //var milliseconds = currentTime * 3
    var timer;


    if (minutes < 10)
    minutes = "0" + minutes
    
    var suffix = "AM";
    if (hours >= 12) {
    suffix = "PM";
    hours = hours - 12;
    }
    if (hours === 0) {
    hours = 12;
    }
      
      if (seconds < 10)
        seconds = "0" + seconds
        
        if (seconds >= 60) {
          seconds = seconds - 60;
        }
      if (seconds === 60) {
        seconds = 60;
      }
      
      if (hours < 10)
        hours = "0" + hours
        
        if (hours >= 12) {
          hours = hours - 12;
        }
      if (hours === 12) {
        hours = 12;
      }
      
      if (milliseconds < 1000)
        milliseconds = "0000";// + milliseconds
        
        if (milliseconds >= 1000) {
          milliseconds = milliseconds - 100; //was 1000
        }
      if (milliseconds === 1000) {
        milliseconds = 1000;
      }
      
    var now = new Date();
    var distance = currentDate - now;
    if (distance < 0) {
    return;
    }
    
      /*var days = Math.floor(distance / day);
      var hours = Math.floor((distance % day) / hour);
      var minutes = Math.floor((distance % hours) / minute);
      var seconds = Math.floor((distance % minutes) / second);
      //var milliseconds = Math.floor(distance % _second) / _millisecond;*/
      
      document.getElementById('countdown').innerHTML = month + '/'; // months
      document.getElementById('countdown').innerHTML += day + '/'; // days
      document.getElementById('countdown').innerHTML += year + '<br>'; // year
      document.getElementById('countdown').innerHTML += hours + ' : '; // hrs
      document.getElementById('countdown').innerHTML += minutes + ' : '; // mins
      document.getElementById('countdown').innerHTML += seconds + ' : '; // secs
      document.getElementById('countdown').innerHTML += milliseconds + ' '; // milliseconds
      document.getElementById('countdown').innerHTML += '<b>' + suffix + '</b>'; // suffix

    }
      timer = setInterval(showRemaining, 1);
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <p id="countdown"></p>
</body>
</html>