Reputation: 402
I have a 1:30 minute timer in JS that belongs to a quiz. In the quiz, if the user selects the wrong answer, the timer is deducted by 10 seconds. That part is working. However, when the timer reaches 1:00, it restarts to 1:59 seconds and never actually goes below 1 minute.
function startTimer() {
var p_time = document.getElementById('time').innerHTML;
var timeArray = p_time.split(/[:]+/);
var min = timeArray[0];
var sec = checkSecond((timeArray[1] - 1));
if (sec === 59) {
min = min - 1
}
document.getElementById('time').innerHTML = min + ":" + sec;
if (min <= 0 && sec == 0) {
clearTimeout(timerRef)
alert("Time is up!")
return;
}
if(min === 1 && sec === 0) {
min = 0;
}
setTimeout(startTimer, 1000);
}
function checkSecond(seconds) {
if (seconds < 10 && seconds >= 0) {
seconds = "0" + seconds
};
if (seconds < 0) {
seconds = "59"
};
return seconds;
}
function wrongTimer () {
var x_time = document.getElementById('time').innerHTML;
var wrongArray = x_time.split(/[:]+/);
var x_min = wrongArray[0];
var x_sec = checkSecond((wrongArray[1]-1));
if(x_sec === 59) {
x_min = x_min - 1
}
x_sec -= 10;
console.log(document.getElementById('time').innerHTML);
console.log("sec " + x_sec);
document.getElementById('time').innerHTML = x_min + ":" + x_sec;
}
I'm calling the wrongTimer function later in my code (not shown). How do make the timer continue to countdown even after possible deductions?
Upvotes: 1
Views: 591
Reputation: 10208
The issue is (sec === 59)
, you're checking if sec
is 59
(Number), but sec
is "59"
(String).
You can either parse the string to a number, of just check if sec
is the string "59"
.
I've just done the latter in the example below, working snippet:
function startTimer() {
var p_time = document.getElementById("time").innerHTML;
var timeArray = p_time.split(/[:]+/);
var min = timeArray[0];
var sec = checkSecond(timeArray[1] - 1);
if (sec === "59") { // <- the fix
min = min - 1;
}
document.getElementById("time").innerHTML = min + ":" + sec;
if (min <= 0 && sec == 0) {
clearTimeout(timerRef);
alert("Time is up!");
return;
}
if (min === 1 && sec === 0) {
min = 0;
}
var timerRef = setTimeout(startTimer, 1000);
}
function checkSecond(seconds) {
if (seconds < 10 && seconds >= 0) {
seconds = "0" + seconds;
}
if (seconds < 0) {
seconds = "59";
}
return seconds;
}
function wrongTimer() {
var x_time = document.getElementById("time").innerHTML;
var wrongArray = x_time.split(/[:]+/);
var x_min = wrongArray[0];
var x_sec = checkSecond(wrongArray[1] - 1);
if (x_sec === 59) {
x_min = x_min - 1;
}
x_sec -= 10;
console.log(document.getElementById("time").innerHTML);
console.log("sec " + x_sec);
document.getElementById("time").innerHTML = x_min + ":" + x_sec;
}
startTimer();
<div id="time">1:05</div>
Upvotes: 2
Reputation: 5708
You are using strict comparison operators ===
for comparisons which only return true if two elements have the same value and are of the same type. The problem is that your seconds variable is a string, so the comparisons to ints will return false regardless of value.
I applied a few other fixes and removed some unnecessary code, check below:
function startTimer() {
var p_time = document.getElementById('time').innerHTML;
var timeArray = p_time.split(":");
var min = timeArray[0];
var sec = checkSecond((timeArray[1] - 1));
if (sec == 59) {
min = min - 1
}
if (min < 0) {
clearTimeout(timerRef)
alert("Time is up!")
return;
}
document.getElementById('time').innerHTML = min + ":" + sec;
var timerRef = setTimeout(startTimer, 1000);
}
function checkSecond(seconds) {
if (seconds < 10 && seconds >= 0) {
seconds = "0" + seconds
};
if (seconds < 0) {
seconds = "59"
};
return seconds;
}
function wrongTimer () {
var x_time = document.getElementById('time').innerHTML;
var wrongArray = x_time.split(/[:]+/);
var x_min = wrongArray[0];
var x_sec = checkSecond((wrongArray[1]-1));
if(x_sec === 59) {
x_min = x_min - 1
}
x_sec -= 10;
console.log(document.getElementById('time').innerHTML);
console.log("sec " + x_sec);
document.getElementById('time').innerHTML = x_min + ":" + x_sec;
}
startTimer();
<div id="time">1:10</div>
Upvotes: 1
Reputation: 21
It may work better for you to refactor your code so that you have a counter in memory keeping track of how many seconds the timer should have (ie 120 when it begins at 2 minutes, then down to 60 when it goes to 1 minute). This set up will be easier to then code into a UX friendly timer (MM:SS) as you will be converting one way always and any additions or deductions to that code will simply be made to that counter and then flow down to your conversions in the UI.
As it stands now, you are finding the time remaining inside your HTML, taking out the time pieces (taking out seconds and minutes) and then doing all of your deductions. This is requires more calculations than are really needed. It also makes it a real pain to go from 1:00 to 0:59.
Nonetheless, you should be warned that if you keep track of this counter variable on the client-side, it could be manipulated by someone clever to give them more time than intended. You'll have to be careful how you insure the integrity of the timer, whether in this solution or in another.
Upvotes: 0