javascript countdown clock

一世执手 提交于 2019-11-30 16:44:11

The answers I see here work pretty well but are not entirely rigorous. Although setInterval() seems like the right function to use, it suffers from a slight "drift" over time. Also, if some other JavaScript function takes a second or more to execute then your countdown clock can get stalled and show the wrong time.

Although these occurrences might be unlikely, greater precision is really not more difficult. What you want is a timer that pulls the clock back from any inaccuracy. You'll need to calculate time off the system clock rather than from the frequency of time intervals, and for this you'll have to give up setInterval() in favor of a series of setTimeout() calls. The following code shows how.

function countdown( elementName, minutes, seconds )
{
    var element, endTime, hours, mins, msLeft, time;

    function twoDigits( n )
    {
        return (n <= 9 ? "0" + n : n);
    }

    function updateTimer()
    {
        msLeft = endTime - (+new Date);
        if ( msLeft < 1000 ) {
            element.innerHTML = "countdown's over!";
        } else {
            time = new Date( msLeft );
            hours = time.getUTCHours();
            mins = time.getUTCMinutes();
            element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) +
                ':' + twoDigits( time.getUTCSeconds() );
            setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
        }
    }

    element = document.getElementById( elementName );
    endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
    updateTimer();
}

Try it: http://jsfiddle.net/mrwilk/qVuHW

If your clock should by chance align very closely to the seconds of the system clock, your countdown timer can appear to "miss beats" due to receiving timeout events just slightly before or just slightly after a one-second interval. The solution is to align your events on the half-second; that is, midway between the beats of the seconds of the system clock. That what the 500's in the code do, where 500ms = ½sec.

The only other matter worth noting is that the code here displays hours as well as minutes and seconds; that is, HH:MM:SS. Computing hours, minutes and seconds from milliseconds is not difficult but is a bit awkward, and it's simplest to let the Date object do this work for you.

Raynos

I've cleaned up the above code and made it format like your example. It also removed the global variables and allows you to create multiple timers.

There's a live link here http://jsfiddle.net/Apnu2/6/

countdown('countdown', 1, 5);
function countdown(element, minutes, seconds) {
    // set time for the particular countdown
    var time = minutes*60 + seconds;
    var interval = setInterval(function() {
        var el = document.getElementById(element);
        // if the time is 0 then end the counter
        if(time == 0) {
            el.innerHTML = "countdown's over!";    
            clearInterval(interval);
            return;
        }
        var minutes = Math.floor( time / 60 );
        if (minutes < 10) minutes = "0" + minutes;
        var seconds = time % 60;
        if (seconds < 10) seconds = "0" + seconds; 
        var text = minutes + ':' + seconds;
        el.innerHTML = text;
        time--;
    }, 1000);
}
                            <script>
            var s=3600;
            var h=Math.floor(s/3600);
            var m=Math.floor((s%3600)/60);
            var sec=(s%60);
            window.clearInterval(x);
            function clock()
            {
             if(m!=0)
             if(sec==0){
             m=m-1; sec=59;} 
             if(h!=0)
             if(m==0){
             h=h-1;m=59;
             sec=59;}
             if((m==0&&h==0&&sec==0))
             $(this).stop();
             --sec;
             var hr=(h<10? "0":"")+h;
             var minu=(m<10? "0":"")+m;
             var second=(sec<10? "0":"")+sec;
             document.getElementById("time").innerHTML=hr+":"+ minu +":"+second ;
            }
            var x=window.setInterval(clock,10);

            </script>
mplungjan

The element in the script is the id of the tag you pass to the function.
So countdown('div1') will show a timer in a tag with id="div1"

However your particular timer does not allow multiple instances and uses a global var called interval.

Generate the JSON on the server and the rest takes care of itself

HERE is an OO version that is more precise since it is only calculating the end time instead of relying on interval which will block if the browser is busy: http://jsbin.com/ujuzo5/edit

And here is my original solution with the help of the good folks at SO here: Broken closure - please help me fix it

<script type="text/javascript">
// generate this on the server and note there is no comma after the last item
var counters = {
  "shoes":{"id":"shoe1","minutes":1,"seconds":5},
  "trousers":{"id":"trouser1","minutes":10,"seconds":0}
};

var intervals = {};

window.onload = function() {
  for (var el in counters) { countdown(counters[el]) };
}
function countdown(element) {
    var minutes = element.minutes;
    var seconds = element.seconds;

    intervals[element.id] = setInterval(function() {
        var el = document.getElementById(element.id);
        if(seconds == 0) {
            if(minutes == 0) {
                el.innerHTML = "countdown's over!";                    
                clearInterval(intervals[element.id]);
                return;
            } else {
                minutes--;
                seconds = 60;
            }
        }
        if(minutes > 0) {
            var minute_text = minutes + (minutes > 1 ? ' minutes' : ' minute');
        } else {
            var minute_text = '';
        }
        var second_text = seconds > 1 ? 'seconds' : 'second';
        el.innerHTML = minute_text + ' ' + seconds + ' ' + second_text + ' remaining';
        seconds--;
        // optionally update the member values
        element.minutes=minutes;
        element.seconds=seconds;
    }, 1000);
}

</script>
shoes: <span id="shoe1"></span><br />
trousers: <span id="trouser1"></span><br />
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!