Question

I've got a ColdFusion application that I am developing that requires a timer that can start, pause, and clear. My problem is that although it works perfectly fine in IE9, Firefox, Opera, Chrome, and Safari, it will not work in IE8 (which is a huge chunk of my userbase). The issue is that when I click and try to stop the timer, instead of the timer stopping, it speeds up. It only does it in IE8 (the other browsers work fine).

-- CLOCK CODE --

function check_timer() {
    if($('#timer').hasClass('start')) {
        $('#timer').val("Stop Timer");
        timer = setInterval ( "increaseCounter()", 1000 );
        $('#timer').removeClass('start')
    }
    else {
        if(typeof timer != "undefined") {
            clearInterval(timer); 
        }

        $('#timer').val("Start Timer");
        $('#timer').addClass('start')
    }
}

function increaseCounter() {
    var secVal;
    var minVal;
    secVal = parseInt($('#counterSec').html(),10) 
    minVal = parseInt($('#counterMin').html(),10)
    if(secVal != 59) {
        secVal = secVal + 1;
        if(secVal < 10) {
            secVal = secVal.toString();
            secVal = "0" + secVal;
        }
        $('#counterSec').html(secVal);
    }
    else {
        if(minVal != 59){
            minVal = minVal + 1;
            if(minVal < 10) {
                minVal = minVal.toString();
                minVal = "0" + minVal;
            }
            $('#counterMin').html(minVal); 
        }
        else {
            $('#counterHour').html((parseInt($('#counterHour').html(),10)+1));
            $('#counterMin').html("00");
        }
        $('#counterSec').html("00");
    }
} 

-- DIV CONTAINING CLOCK --

<div class="supportClock" style="width:150px; border-radius:20px;" align="center">
            <span id="addZeroHour"></span>
            <span id="counterHour">00</span>
            :<span id="addZeroMin"></span>
            <span id="counterMin">00</span>
            :<span id="addZeroSec"></span>
            <span id="counterSec">00</span>
        </div>

-- BUTTON TO ACTIVATE CLOCK --

<input type="button" id="timer" class="start" value="Start Timer" onclick="check_timer()">
Was it helpful?

Solution 2

Have a look here: http://jsfiddle.net/qEATW/3/

  1. Even if you set an interval to be, for example, one second, it won't necessarily be one second between calls.
  2. For timeouts and intervals, always pass in the function, never a string: setInterval(increaseCounter, 1000)
  3. There's no reason to parse values from the DOM. It's incredibly inefficient to do so. If you instead use Date differences, you can simply store one variable (start time), and get hours/mins/seconds since that time. You can update the view however often you like and it will always be accurate.
  4. I personally prefer "recursive" timeouts as opposed to intervals. With intervals, you'll always need to take that extra step to clear the interval when you want it to stop. You can stop a timeout loop in several different ways, and it tends to be easier to understand what's going on. Timeouts also allow us the flexibility of changing the time between calls (not that that is relevant here).
  5. It is considered a bad practice to bind event handlers inline (on the HTML element). If you are already using jQuery, there's really no excuse for this as jQuery makes the process so very simple.
  6. I got rid of the "addZero" spans that you had. I'm not sure what you were doing with them, but they weren't necessary and only served to clutter the markup.

HTML:

<div class="supportClock" style="width:150px; border-radius:20px;" align="center">
    <span id="counterHour">00</span>
    : <span id="counterMin">00</span>
    : <span id="counterSec">00</span>
</div>
<input type="button" id="timer" class="start" value="Start Timer">

JS:

(function(){
    var clock = $(".supportClock"),
        hr = $("#counterHour"),
        min = $("#counterMin"),
        sec = $("#counterSec"),       
        running = false,
        startTime,
        timeout;

    function updateClock(){
        var time = (new Date()) - startTime,
            hrs = Math.floor(time / 1000 / 60 / 60),
            mins = Math.floor(time / 1000 / 60 - hrs * 60),
            secs = Math.floor(time / 1000 - mins * 60 - hrs * 60 * 60);

        hr.text(hrs > 9 ? hrs : '0' + hrs);
        min.text(mins > 9 ? mins: '0' + mins);
        sec.text(secs > 9 ? secs : '0' + secs);

        timeout = setTimeout(updateClock, 1000/2);
    }

    $("#timer").click(function(){
        if (!running){
            running = true;
            this.value = "Stop Timer";
            startTime = new Date();
            updateClock();
        }
        else{
            running = false;
            this.value = "Start Timer";
            clearTimeout(timeout);
        }
    });
})();

OTHER TIPS

add this to the top of your script(outside the functions):

var timer;

Otherwise you will never run into this branch:

if(typeof timer != "undefined")

The reason: there is an element with the ID "timer", you may access it by using timer without the suggested modification and timer will never be of type "undefined"

Or simply use another name for the timeout-variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top