0
 <script>
var interval;
var minutes = 1;
var seconds = 5;
window.onload = function() {
    countdown('countdown');
}

function countdown(element) {
    interval = setInterval(function() {
        var el = document.getElementById(element);
        if(seconds == 0) {
            if(minutes == 0) {
                el.innerHTML = "countdown's over!";                    
                clearInterval(interval);
                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--;
    }, 1000);
}
</script>

this is a good countdown clock and i want to show the time in datalist how do i do it? like in this site www.1buy1.co.il

3
  • You'll have to be a lot clearer about what you're trying to achieve to get any useful answers to this question. What do you want in the data list? How does it relate to the countdown? Commented Jan 3, 2011 at 12:33
  • i have a datalist and in the datalist i have a table and in one of the cells i want to put a div or lable or something like this that calls to the function countdown(the code) and i want the function to get number of seconds using Eval according to a product Commented Jan 3, 2011 at 12:41
  • Take a look here forums.aspfree.com/code-bank-54/… it's something I wrote some while ago, if you want I can help you integrate it with your existing code. :) Commented Jan 3, 2011 at 13:28

4 Answers 4

10

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is a nice countdown. I am trying to use your code but in a slightly different way. Could you please help me. My question is here. stackoverflow.com/questions/29281230/… Thank you!
4

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);
}

3 Comments

@roi you should put the JavaScript code after the countdown element, then it will work.
@roi look at the jsfiddle. I cant test it in ie8 but it should work in chrome/ff
how could I pause this timer, and resume it?
1
                            <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>

1 Comment

Pehaps you could add a description along with the code to explain how it solves the problem?
0

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 />

3 Comments

it doesn't work i want to do this: i have a datalist and in the datalist i have a table and in one of the cells i want to put a div or lable or something like this that calls to the function countdown(the code) and i want the function to get number of seconds using Eval according to a product
That is what this code is needed for: var counters = { "shoes":{"id":"shoe1","minutes":1,"seconds":5}, "trousers":{"id":"trouser1","minutes":10,"seconds":0} }; You just generate that on the server
the time is not moving i can see the timer but thats it it doesn't count down

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.