setInterval for stopwatch - javascript

I'm trying to make a stopwatch. Here's the code:
var min = 0, sec = 0, censec = 0
$("#startBtn").on("click", function() { // when start button is clicked
$(this).hide(); // start is hidden
$("#stopBtn").show(); // stop is shown
setInterval(add, 10); // the censec will be increased every 10 millisecond.
$("#censec").text(censec);
})
function add() {
censec++;
if (censec == 100) {
censec = 0;
sec++;
if (sec == 60) {
sec = 0;
min++;
}
}
}
The problem is that setInterval() happens only at once. The censec only changes from 00 to 1. That's it.
P.S. I'm new to coding, so if there are other mistakes, please don't hesitate to tell me.

The setInterval calls to add will definitely repeat. But your code is only ever showing the value of censec once, when you start the timer.
If you want to update the display every hundredth of a second, put the code showing the value in add.
Separately, the code as it is in the question won't run at all, because it has a ReferenceError on the first line. Those ; should be ,.
Example (this also stores the timer's handle and clears the timer when you click the stop button):
var min = 0, sec = 0, censec = 0;
// Note ---^--------^
function add() {
censec++;
if (censec == 100) {
censec = 0;
sec++;
if (sec == 60) {
sec = 0;
min++;
}
}
$("#censec").text(censec);
}
var timer = 0;
$("#startBtn").on("click", function() { //when start button is clicked
$(this).hide(); //start is hidden
$("#stopBtn").show(); //stop is shown
timer = setInterval(add,10); //the censec will be increased every 10 millisecond.
});
$("#stopBtn").on("click", function() {
clearInterval(timer);
timer = 0;
$(this).hide();
$("#startBtn").show();
});
<input type="button" id="startBtn" value="Start">
<input type="button" id="stopBtn" value="Stop" style="display: none">
<div id="censec"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note that although it may be mostly fine to use setInterval for displaying, using it to track the elapsed time is a bad idea; it frequently doesn't fire precisely.
Instead, record when you started
var start = Date.now();
...and then when the timer fires, figure out how long it's been since you started
var elapsed = Date.now() - start;
Then use the value (milliseconds) in elapsed to figure out your display.

Your variable declarations have ; instead of , .
Also checking numbers on equality should be done by using === but that is not the problem here.
Your also not updating the view in your timer. So updating of your html should also be in your function that is called by the timer.
If the goal is to use real seconds and milliseconds, I also suggest using the Date type because your timer will be late and not real-time. So still use the timer with the interval you like but in the add function you call the date object. You can replace the 3 vars for one datetime of type Date which will give you the granularity that you like.
var dateTimeStart = null, censecElement = null, timer = null;
$("#startBtn").on("click", function() {//when start button is clicked
$(this).hide(); // start is hidden
$("#stopBtn").show(); // stop is shown
if(timer === null) {
// timer was not started
dateTimeStart = new Date();
timer = setInterval(updateCensec, 10); //the censec will be increased every 10 millisecond.
console.log("Started timer");
}
});
$("#stopBtn").on("click", function() {//when stop button is clicked
$(this).hide(); // stop is hidden
$("#startBtn").show(); // start is shown
if(timer) {
// timer is started/running
clearInterval(timer);
console.log("Stopped timer");
}
timer = null;
});
function updateCensec() {
var sensec = 0, sec = 0, dateTimeNow = new Date(), diffMilliseconds = 0;
diffMilliseconds = dateTimeNow - dateTimeStart;
censec = parseInt((diffMilliseconds % 600 ) / 10); // convert milliseconds to centi seconds
sec = parseInt(diffMilliseconds / 600);
if(censecElement === null) {
censecElement = $("#censec");
}
censecElement.text(sec + ":" + censec);
}
I would like to suggest that you do not update your view every 10 milliseconds even if you want your stopwatch to show time in centiseconds.

Related

For loop with a timeout doesn't seem to work and gives weird numbers

I want to make a countdown in javascript, with simple variables, for loop, set timeout.
I get stuck when trying to make a for loop update realtime (every second) right now I get -1 in webpage.
//HTML PART
<p id=timer>0</p>
//JS PART
var timer = 10;
var text = "";
function f() {
for (timer; timer > 0; timer--) {
text += timer + "<br>";
}
timer--;
if( timer > 0 ){
setTimeout( f, 1000 );
}
}
f();
document.getElementById("timer").innerHTML = timer;
Please explain the error and if I'm doing any stupid mistakes
Looks like you want to show timer value from 10 to 0 by changing the value every second. If so, you can do like this:
1. You need to correct your html by putting quotes around timer like this <p id="timer">0</p>
2. You need to remove for loop as I have commented.
3. Move document.getElementById("timer").innerHTML = timer; inside function f().
var timer = 10;
//var text = "";
function f() {
//for (timer; timer > 0; timer--) {
// text += timer + "<br>";
//}
document.getElementById("timer").innerHTML = timer;
timer--;
if (timer >=0) {
setTimeout(f, 1000);
}
}
f();
<p id="timer">0</p>
You can do it like so, I provided comments in code for explanation:
var count = 10;
function timer(targetValue) {
// display first number on screen
document.getElementById("timer").textContent = count;
// decrease count by 1
count--;
// check if timer is still grater than target value
if (count >= targetValue) {
// call timer() function every second to update
setTimeout(timer, 1000, targetValue);
}
}
timer(0);
Counts down from 10 to 0.
Want to count down from 10 to 5? Simply use timer(5)

Timer does not actually stop after pause button is clicked

Timer is displayed as if it is kind of stop after pause button is clicked, but when i click resume i find out that counter continue to countdown behind the scene. I guess there are issues with setInterval. Please help me. My project on CodePen for reference if you need.
My timer function
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
displayTimerLeft(seconds);
console.log({
now,
then
});
countdown = setInterval(() => {
if (!isPaused) {
const remainSeconds = Math.round((then - Date.now()) / 1000);
if (remainSeconds < 0) {
clearInterval(countdown);
return;
}
displayTimerLeft(remainSeconds);
}
}, 1000);
}
Pause and start click events
pause.addEventListener('click', function() {
isPaused = true;
return;
})
start.addEventListener('click', function() {
isPaused = false;
})
Looking at your code, I suppose the problem is you keep the same then value, which is ultimately a timestamp at which the timer should end. Right now, instead of pausing the countdown, you stop the display from changing.
I would advise using your variable seconds instead (and calculating display using modulo %), and decreasing it every second. That way, pausing the display would effectively pause the decreasing.
Keep a reference of the current time and manually add a second at each tick.
function timer(seconds) {
clearInterval(countdown);
const t = new Date();
const end = t.getTime() + seconds * 1000;
displayTimerLeft(seconds);
console.log({
t,
end
});
countdown = setInterval(() => {
if (!isPaused) {
const remainSeconds = Math.round((end - t.getTime()) / 1000);
if (remainSeconds < 0) {
clearInterval(countdown);
return;
}
displayTimerLeft(remainSeconds);
t.setSeconds(t.getSeconds() + 1);
}
}, 1000);
}
Demo: http://codepen.io/miguelmota/pen/wgMzXY
setInterval returns a unique id that can be used to stop the timer using clearInterval:
var id = setInterval(function(){
console.log('running every 300 ms');
},300);
clearInterval(id) // stop timer

Js Timeout Display

I am not sure if this possible using my current method, but I am wondering if it is possible to show the timeout as a counter on page.
I am creating a page to show data entering the database in 15 second intervals however the timeout can be changed.
var counter = 15 * 1000
var autoRefresh = function(){
clearInterval(interval);
interval = setInterval(autoRefresh, counter);
$.pjax.reload({container:"#content",async:false, timeout: 2000});
return false;
}
var interval = setInterval(autoRefresh, counter);
Ideally I need to show a countdown timer till the next refresh. Is it possible or is there an alternate route I can take to achieve this?
The only real way is to run your interval every second, display the countdown and, if 15 seconds have past, do what you want to do.
var counter = 15 * 1000;
var currentCycle = 0;
var autoRefresh = function(){
currentCycle++;
if (currentCycle >= (counter/1000)) {
currentCycle = 0;
$.pjax.reload({container:"#content",async:false, timeout: 2000});
} else {
console.log((counter/1000-currentCycle)+' seconds remaining');
}
return false;
}
var interval = setInterval(autoRefresh, 1000);

Change var onclick button, javascript

I need a pause button for this timer. And unfortunately, it's not working.
When id "button-pause" is clicked, I need to set "var pressed = true".
If not, run the script below "if(!pressed){" and let "var pressed = false".
What's wrong?
HTML
<span id="button-pause">
<span class="music"></span>
<img src='img/icons/pause.png' alt='Stop music'>
</span>
JavaScript
var minutes = 60;
// Set number of seconds remaining after which to trigger a warning color
var warning = 59;
var pressed = false;
k = document.getElementById('button-pause');
k.onclick = function () {
pressed = true;
}
if(!pressed){
// Declare variables
var timerEl, seconds, timer;
// Get a reference to the HTML element
timerEl = document.getElementById('tim');
// Calculate total seconds
seconds = 1*minutes;
// Updates the timer element
function updateTimer() {
var m,s;
// Get whole minutes
m = Math.floor(seconds/60);
// Get left-over seconds
s = seconds % 60;
// Pad anything below 10 with a leading zero
s = (s < 10) ? "0"+s : s;
// Write time to HTML element
timerEl.innerHTML = m + ":" + s;
// Decrement seconds
seconds--;
// Add warning class when we hit threshold
if(seconds < warning) {
timerEl.classList.add('warning');
}
// Clear timer when we hit zero
if(seconds < 0) {
clearInterval(timer);
window.location.href='index.php?mode=workout&workoutid=test&status=done';
}
}
}
timer = setInterval(updateTimer, 1000);
Your first problem is using the same variable for two things
var pressed = false; <-- store a boolean
pressed = document.getElementById('button-pause'); <--override the boolean with the button
Second issue is the JavaScript code is not going to change when you click the button. It will set the variable, but the code that has already run will not update magically. You would need to add the code to some sort of function and trigger it when the button is clicked or when the page is loaded.

How to run a javascript function X seconds?

I am using setInterval to run a Javascript function that generates a new, random integer in a div. the timer starts when I click on the div. I am having problems with stopping it form generating new numbers after five seconds.
Using setTimeout, I hide the div after 5 seconds; that stops random numbers, but I lose the div.
How can I efficiently stop the generating of numbers in the div, and not hide it?
HTML:
<div id="div" onmousedown='F();'>Click here</div>
JS:
function F(){
var div = document.getElementById("div");
setInterval(function(){
var number = Math.floor(Math.random()*28) ;
div.innerHTML = number;
}, 1000);
setTimeout(function(){
div.style.display = 'none';
},5000);
};
Just use a counter to keep track of the number of times the interval has ticked and then use clearInterval to stop it:
var count = 0;
var intervalID = setInterval(function() {
// generate your random number
count++;
if (count === 5) {
clearInterval(intervalID);
}
}, 1000);
Something hastily written, but what you want to do is keep track of your interval handle and then clear it. You can do this with a setTimeout
var forXsecs = function(period, func) {
var handle = setInterval(func, 1000);
setTimeout(function() { clearInterval(handle); }, period * 1000);
}
The timing is not perfect. Matt's answer would also work.
Another option is a slight change on Matt's answer that removes setInterval and just uses timeouts.
var count = 0;
var forXsecs = function(period, func) {
if(count < period) {
func();
count++;
setTimeout(function() {forXsecs(period, func);}, 1000);
} else {
count = 0; //need to reset the count for possible future calls
}
}
If you just want to simply let it run once each second and that 5 times you can do it like this:
HTML:
<div id="5seconds"></div>
JS:
var count= 0;
setInterval(function(){
if(count < 5){
document.getElementById('5seconds').innerHTML = Math.random();
count++
}
},1000);
This will generate a random number each second. until 5 seconds have passed
you should use clearInterval to stop the timer.
To do so, you pass in the id(or handle) of a timer returned from the setInterval function (which creates it).
I recommend clearing the interval timer (using clearInterval) from within the function being executed.
var elm = document.querySelector("div.container");
var cnt = 0;
var timerID;
function generateNumber()
{
cnt += 1;
elm.innerText = cnt;
if (cnt >= 5) {
window.clearInterval(timerID);
}
}
timerID = window.setInterval(generateNumber, 1000);
.container {display:block; min-width:5em;line-height:5em;min-height:5em;background-color:whitesmoke;border:0.1em outset whitesmoke;}
<label>1s Interval over 5s</label>
<div class="container"></div>

Categories