timer speeds up on second round onwards - javascript

I have borrowed some JS code to help me create a timer for 65 seconds. My JS knowledge is basic but I managed to modify the script to work the way I want it to. However when I click on the play button the timer speeds up from the second round onwards.
HTML:
<div id="rightCol">
<span id="countdown" class="timer">Timer About to Start! </span>
<div>
<input type="button" value="Play" id="play">
</div>
</div>
JS:
var seconds = 65;
function secondPassed() {
    var minutes = Math.round((seconds - 30)/60);
    var remainingSeconds = seconds % 60;
    if (remainingSeconds < 10) {
        remainingSeconds = "0" + remainingSeconds; 
    }
    document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
    if (seconds == 0) {
        clearInterval(countdownTimer);
        document.getElementById('countdown').innerHTML = "Time's Up!";
document.getElementById("passage_text").disabled = true;
    } else {
        seconds--;
    }
}
 
var countdownTimer = setInterval('secondPassed()', 1000);
$("#play").click(function(){
seconds = 65;
var countdownTimer = setInterval('secondPassed()', 1000);
$('#passage_text').attr('disabled', false).focus();
$("#passage_text").val('');
});
I read some of the other answers similar to mine Count down timer speeds up but I don't fully understand how the secondPassed() function works to fix it.

You need to clear interval on play functionality too and make countdownTimer global. Also it's better to pass function handler to setInterval instead of string as this will work as eval function and not recommended
var seconds = 65;
var countdownTimer = null; // make it global
function secondPassed() {
var minutes = Math.round((seconds - 30)/60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "Time's Up!";
document.getElementById("passage_text").disabled = true;
} else {
seconds--;
}
}
countdownTimer = setInterval(secondPassed, 1000); // removed var and passing handler instead of string.
$("#play").click(function(){
seconds = 65;
clearInterval(countdownTimer); // clear interval
countdownTimer = setInterval(secondPassed, 1000); // removed var to use global countdownTimer variable
$('#passage_text').attr('disabled', false).focus();
$("#passage_text").val('');
});
See my JS comments above

Related

Countdown It does not Work with click button

I have a simple question. I want to make this code work with the Reset time button when the time is start again from 30 min delete the ( You are Ready! ) and start the time
var seconds = 30;
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "You are Ready!";
} else {
seconds--;
}
}
var countdownTimer = setInterval('secondPassed()', 1000);
<span id="countdown" class="timer">
Reset time
I created a new function to reset the seconds and restart the timer and linked it to the button. I have also isolated at the start of the js code the variables that will count the seconds and hold the reference to the Interval.
is this what you are looking for?
var seconds;
var countdownTimer;
function startTimer() {
if (!seconds || seconds == 0) {
seconds = 30;
clearInterval(countdownTimer);
countdownTimer = setInterval(secondPassed, 1000)
secondPassed();
}
}
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "You are Ready!";
} else {
seconds--;
}
}
startTimer();
<html>
<body>
<div>
<span id="countdown" class="timer"></span>
</div>
Reset time
</body>
</html>
Here create a separate function where after clicking - it disables the button, sets the timer, and changes button text.
In secondPassed method, if seconds == 0, it enables the button, so that you can start count down again.
var seconds = 30;
var countdownTimer;
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0)
{
clearInterval(countdownTimer);
document.getElementById('reset').disabled = false;
document.getElementById('countdown').innerHTML = "You are Ready!";
} else
{
seconds--;
}
}
function start(){
seconds = 30;
document.getElementById('reset').innerHTML = "Reset";
document.getElementById('reset').disabled = true;
countdownTimer = setInterval('secondPassed()', 1000);
}
//on load call
start();
<div>
<span id="countdown" class="timer"/>
</div>
<button id="reset" onclick="start()">
Start
</button>
Let's assume something quite basic, like the following:
<div>00:00</div>
<button>Reset</button>
Below is an approach you could take, fully-commented.
// We'll start by getting a couple element references
const label = document.querySelector("div");
const button = document.querySelector("button");
// Next, we'll bind-up the click handler for the button
button.addEventListener("click", () => {
// When the user clicks the button, we'll set the time
// limit to 30 minutes and proceed
let timer = 60 * 30;
// Disable the button to prevent further clicks
button.disabled = true;
button.dataset.default = button.textContent;
button.textContent = "Now counting down!";
// Let's setup some code that will be executed every second
button.interval = setInterval(() => {
// This decimal will be a number like 29.9521
const decimal = timer / 60;
// We'll convert 29.9521 into 29, for 29 minutes
const wholeMinute = Math.floor(decimal);
// Next, we'll take the .9521 and multiply by 60 for seconds
const wholeSecond = Math.round(60 * (decimal - wholeMinute));
// We'll pad both of the numbers so they always have a leading 0
const lblMin = wholeMinute.toString().padStart(2, 0);
const lblSec = wholeSecond.toString().padStart(2, 0);
// As long as we aren't out of seconds
if (timer >= 0) {
// Reduce the timer by 1 second
timer = timer - 1;
// And print the new label on our label element
label.textContent = `${ lblMin }:${ lblSec }`;
// Then return, so we don't execute what comes next
return;
}
// If we made it this far, our timer ran out
// Start by enabling the button
button.disabled = false;
// Restore the original text of the button
button.textContent = button.dataset.default;
// And clear our interval, as it is no longer needed
clearInterval(button.interval);
// Our interval will 'tick' once every second (1000 milliseconds)
}, 1000);
});

Javascript Descending Timer with Minutes, Seconds and Milliseconds

I have searched all over internet a lot but could not find solution.
I want a timer with descending order with minutes, seconds and milliseconds. i.e. 05:59:999 -> 5 Minutes, 59 Seconds, 999 Milliseconds.
Below is my code which give me just minutes and seconds :
var countdownTimer = '';
var upgradeTime = 300; // total sec row from the table
var seconds = upgradeTime;
function timer()
{
var days = Math.floor(seconds/24/60/60);
var hoursLeft = Math.floor((seconds) - (days*86400));
var hours = Math.floor(hoursLeft/3600);
var minutesLeft = Math.floor((hoursLeft) - (hours*3600));
var minutes = Math.floor(minutesLeft/60);
var remainingSeconds = seconds % 60;
document.getElementById('timer1').innerHTML = pad(minutes) + " : " + pad(remainingSeconds);
document.getElementById("timer1").style.border = "1px solid";
document.getElementById("timer1").style.padding = "4px";
}
function pad(n)
{
return (n < 10 ? "0" + n : n);
}
$('#acstart').on('click', function(e) // Start the timer
{
clearInterval(countdownTimer);
countdownTimer = setInterval('timer()', 1000);
});
I found fiddle with seconds and milliseconds here is the link :
http://jsfiddle.net/2cufprgL/1/
On completion of the timer I need to call other action.
Thanks
Using the fiddle you included, you only need to update the displayCount function to get the result you want.
function displayCount(count) {
let res = Math.floor(count / 1000);
let milliseconds = count.toString().substr(-3);
let seconds = res % 60;
let minutes = (res - seconds) / 60;
document.getElementById("timer").innerHTML =
minutes + ' min ' + seconds + ' s ' + milliseconds + ' ms';
}
Note that your fiddle has the correct approach to countdown, everytime the timer ticks it measures the actual time left it doesn't assume that the timer was 'on time'.
I wouldn't call this clean. But I did follow through using your code. I did change it to recursive setTimeout() though.
What I did is call the interval faster than 1000ms, set a specific speed variable and then properly decrement seconds while checking for a flag when seconds becomes 0, this flag then calls stopTimer().
var countdownTimer = '';
var upgradeTime = 3; // total sec row from the table
var seconds = upgradeTime;
var milliseconds = seconds * 1000;
var speed = 50; //interval speed
function timer()
{
milliseconds = (seconds * 1000) - speed; //decrement based on speed
seconds = milliseconds / 1000; //get new value for seconds
var days = Math.floor(seconds/24/60/60);
var hoursLeft = Math.floor((seconds) - (days*86400));
var hours = Math.floor(hoursLeft/3600);
var minutesLeft = Math.floor((hoursLeft) - (hours*3600));
var minutes = Math.floor(minutesLeft/60);
var remainingSeconds = (seconds % 60).toFixed(3);
if(seconds <= 0){ stopTimer(); return; } //sets a flag here for final call
document.getElementById('timer1').innerHTML = pad(minutes) + " : " + pad(remainingSeconds);
document.getElementById("timer1").style.border = "1px solid";
document.getElementById("timer1").style.padding = "4px";
setTimeout('timer()', speed);
}
function stopTimer(){
clearTimeout(countdownTimer);
console.log("IT HAS BEEN DONE");
document.getElementById('timer1').innerHTML = "00 : 00.000"
}
function pad(n)
{
return (n < 10 ? "0" + n : n);
}
clearTimeout(countdownTimer)
countdownTimer = setTimeout('timer()', speed);
<div id="timer1"></div>
Something that sorta works logically right now. It's a tad unstable because of what I was trying to do. https://codesandbox.io/s/8xr1kx8r68
Momentjs with Countdown library - its a little outdated and unmaintained but looks like it does something like what you want.
https://github.com/icambron/moment-countdown
http://countdownjs.org/readme.html

Js code always runs even i don't hit the button

I have a js code and I wanna run it when I click the button.It's seems ok to me but it's run even i don't hit the button.
Probably it has a simple answer but I couldn't handle it.I'm new....
var upgradeTime = 600;
var seconds = upgradeTime;
function timer() {
var days = Math.floor(seconds/24/60/60);
var hoursLeft = Math.floor((seconds) - (days*86400));
var hours = Math.floor(hoursLeft/3600);
var minutesLeft = Math.floor((hoursLeft) - (hours*3600));
var minutes = Math.floor(minutesLeft/60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML =
days + ":" + hours + ":" + minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "Tamamlandı.";
} else {
seconds--;
}
}
var countdownTimer = setInterval('timer()', 1000);
<span id="countdown" class="timer"></span>
<input id="" type="button" value="clickme" onclick="timer();" />
You need to remove var countdownTimer = setInterval('timer()', 1000);
outside the function:
You can include all your core logic to a new function coreTimer()
Call coreTimer() from timer()
make sure countdownTimer is declared in global scope so that it can be cleared using clearInterval inside coreTimer() function.
var upgradeTime = 10;
var seconds = upgradeTime;
var countdownTimer;
function timer() {
countdownTimer = setInterval('coreTimer()', 1000);
}
function coreTimer() {
var days = Math.floor(seconds / 24 / 60 / 60);
var hoursLeft = Math.floor((seconds) - (days * 86400));
var hours = Math.floor(hoursLeft / 3600);
var minutesLeft = Math.floor((hoursLeft) - (hours * 3600));
var minutes = Math.floor(minutesLeft / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = days + ":" + hours + ":" + minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "Tamamlandı.";
} else {
seconds--;
}
}
<span id="countdown" class="timer"></span>
<input id="" type="button" value="clickme" onclick="timer();" />
setInterval method calls a function or evaluates an expression at specified intervals. So the statement
var countdownTimer = setInterval('timer()', 1000);
will execute your timer function every 1000 milliseconds. Hence your function is getting called even when you are not clicking the button. You need to modify that statement accordingly or remove it completely.

Add a timer to online quiz that submits the quiz

I am developing a web based system wherein user can give tests submitted by admin, the issue is i want to implement a timer that can initiate at start of the quiz and autosubmit the test as soon as it ends , need help on how do i implement read a lot of aanswers but did not help specific to my project .`
<span id="countdown" class="timer"></span>
<script>
var seconds = 40;
function secondPassed() {
var minutes = Math.round((seconds - 30)/60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = "Buzz Buzz";
} else {
seconds--;
}
}
var countdownTimer = setInterval('secondPassed()', 1000);
</script>
`

live downcounter with javascript or jquery

counter that i can change time to remain if i want from db
i have a time stamp in table in db that maybe change
now i want for example every 30sec check that and if changed my down-counter changing
my js script is:
<script>
var seconds = 100;
function secondPassed() {
var minutes = Math.round((seconds - 30)/60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = '0' + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ':' + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('countdown').innerHTML = 'Times Up!';
document.getElementById('passage_text').disabled = true;
} else {
seconds--;
}
}
var countdownTimer = setInterval('secondPassed()', 1000);
</script>
Try changing this:
var countdownTimer = setInterval('secondPassed()', 1000);
to this:
var countdownTimer = setInterval(secondPassed, 1000);
What isn't working in your case, exactly?
BTW: Try caching reference on frequently used DOM element. See this alternative using much simpler code for formatting your time.
var display = document.getElementById('countdown');
var seconds = 100, timer;
function secondPassed() {
if ( --seconds == 0 ) {
window.clearInterval( timer );
// your code here executing when count down has finished ...
} else {
display.innerHTML = Math.floor( seconds / 60 ) + ':' + String( "0" + ( seconds % 60 ) ).substr( -2 );
}
}
timer = window.setInterval( secondPassed, 1000 );

Categories

Resources