I am implementing a stopwatch by using Javascript. I have basic html document setup and a javascript file called stopwatch.js in which I have the following code. I make use of setInterval function to execute the clockRunning function every 1 second(1000ms). This gives me control over sec, min and hour to increment them accordingly, but I am having difficulty with inserting millisecond into the stopwatch. How should I increment the millisecond from 0 to 1000 and then reset to zero?
I have tried by decreasing the interval time for setInterval function to be called every 1ms and then set millisecond variable to time%1000 in which time variable is increased by 1 every time the function is called. But it does not give the result I want. The millisecond seems to be increasing way too slow.
var running = 0
var time = 0;
var hour = 0;
var min = 0;
var sec = 0;
var millisec = 0;
function start(){
started = window.setInterval(clockRunning, 1000);
}
function stop(){
window.clearInterval(started);
}
function clockRunning(){
time++;
sec++;
if (sec == 60){
min += 1;
sec = 0;
if (min == 60){
hour += 1;
min = 0;
}
}
document.getElementById("display-area").innerHTML = (hour ? (hour > 9 ? hour : "0" + hour) : "00")
+ ":" + (min ? (min > 9 ? min : "0" + min) : "00") + ":" + (sec > 9 ? sec : "0"
+ sec);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Stopwatch</title>
<script src="stopwatch.js"></script>
<style>
#display-area { font-size: 20pt; }
</style>
</head>
<body>
<div>
<output id="display-area">00:00:00.000</output>
</div>
<div>
<button id="toggle-button" onClick="start()">Start</button>
<button id="toggle-button" onClick="stop()">Stop</button>
<button id="reset-button">Reset</button>
</div>
</body>
</html>
You should keep track of the starting time then subtract that time from the current time using a Date:
var timeBegan = null
, timeStopped = null
, stoppedDuration = 0
, started = null;
function start() {
if (timeBegan === null) {
timeBegan = new Date();
}
if (timeStopped !== null) {
stoppedDuration += (new Date() - timeStopped);
}
console.log(stoppedDuration);
started = setInterval(clockRunning, 10);
}
function stop() {
timeStopped = new Date();
clearInterval(started);
}
function reset() {
clearInterval(started);
stoppedDuration = 0;
timeBegan = null;
timeStopped = null;
document.getElementById("display-area").innerHTML = "00:00:00.000";
}
function clockRunning(){
var currentTime = new Date()
, timeElapsed = new Date(currentTime - timeBegan - stoppedDuration)
, hour = timeElapsed.getUTCHours()
, min = timeElapsed.getUTCMinutes()
, sec = timeElapsed.getUTCSeconds()
, ms = timeElapsed.getUTCMilliseconds();
document.getElementById("display-area").innerHTML =
(hour > 9 ? hour : "0" + hour) + ":" +
(min > 9 ? min : "0" + min) + ":" +
(sec > 9 ? sec : "0" + sec) + "." +
(ms > 99 ? ms : ms > 9 ? "0" + ms : "00" + ms);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Stopwatch</title>
<style>
#display-area { font-size: 20pt; }
</style>
</head>
<body>
<div>
<output id="display-area">00:00:00.000</output>
</div>
<div>
<button id="toggle-button" onClick="start()">Start</button>
<button id="toggle-button" onClick="stop()">Stop</button>
<button id="reset-button" onClick="reset()">Reset</button>
</div>
</body>
</html>
The reason you were seeing the milliseconds "lagging" before was that setInterval is notorious for not firing exactly when you specify. You can get around this using the strategy above.
Update: You could keep track of how long the timer has "paused" between resets. Updated my answer to accommodate this.
complete code here
$(document).ready(function () {
var milliseconds;
var hours;
var minutes;
var seconds;
var interval;
var count = 0;
var lap;
var i = 0;
$(".heading").slideDown("slow"); //slide down heading countdown.
// click function to start timer
$(".start").click(function () {
$(".start").hide();
$(".pause").show(100); // show pause button
$("#end").text("Stopwatch Started"); // change text.
interval = setInterval(newtimer, 10); // run the countdown interval of 1000 millisecond
});
function newtimer() {
hours = parseInt(count * 10 / 1000 / 60 / 60);// calculate hours
minutes = parseInt(count * 10 / 1000 / 60); // calculate minutes
seconds = parseInt((count * 10 / 1000)%60);// calculate seconds
milliseconds = parseInt((count*10) % 1000); // calculate milliseconds
/* display digits in clock manner */
hours = hours < 10 ? "0" + hours : hours;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
count++; // increment in count.
$(".seconds").text(hours + " : " + minutes + " : " + seconds + " : " + milliseconds);
}
/* click function to pause timer*/
$(".pause").click(function () {
$(".start").hide(); //hide start button
$(".restart").hide(); //hide restart button
$(".pause").hide();
$(".resume").show(); // show resume button.
$("#end").text("Stopwatch Paused");
clearInterval(interval); //clear interval will stop the count.
i = i + 1;
lap = " " + hours + " : " + minutes + " : " + seconds + " : " + milliseconds;
$(".lap").append('<p>' + 'Time Lap' + "-" + i + lap + '</p>'); // add p tag in div and count no. of laps.
});
/* click function to resume the countdown */
$(".resume").click(function () {
$("#end").text("Stopwatch Resumed");// change end text.
$(".pause").show();
$(".resume").hide();
interval = setInterval(newtimer, 10);// interval to function new timer. count will remain same where paused.
});
/* click function to stop stopwatch */
$(".stop").click(function () {
$("#end").text("Stopwatch Stopped");
$(".restart").show(); //show restart button
$(".resume").hide(); // hide resume button
$(".start").hide();// hide start button
$(".pause").hide();
$(".lap p").remove(); // remove laps.
clearInterval(interval);
});
/*click function to restart stopwatch*/
$(".restart").click(function () {
$("#end").text("Stopwatch Restarted");// change end text.
$(".restart").hide();
$(".pause").show();
count = 0; // count reset to zero
interval = setInterval(newtimer, 10); //time interval to function new timer
});
/* click function on class reset to reset the countdown */
$(".reset").click(function () {
$(".seconds").text("00 : 00 : 00 : 00"); // set display to initial value.
$(".resume").hide(); // hide resume button
$(".start").show(); // show start button
$(".pause").hide(); // hide pause button
$(".restart").hide(); // hide restart button
$("#end").text(" "); // change end text
$(".lap p").remove(); // remove p tag from div
clearInterval(interval); // clear interval
count = 0; // reset count to initial value.
});
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>stopwatch</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script></head>
<body style="font-family: cursive;">
<div class="container-fluid clearfix" style="padding:100px; background-color:lightgrey;">
<div style="width:25%; float:left"><img src="./bn.jpg" alt="stopwatch" style="width:100%"></div>
<div class="heading" style="color:#165caa;display:none;margin-left: 365px;font-size: 84px">STOPWATCH</div>
<div class="seconds" style="font-size: 46px;text-align:center;margin-top:30px "> 00 : 00 : 00 : 00</div>
<div style="text-align:center;">
<button class="start mt-3 px-4 btn btn-success">START</button>
<button class="restart mt-3 px-4 btn btn-success" style="display:none">RESTART</button>
<button class="resume mt-3 px-4 btn btn-success" style="display:none">RESUME</button>
<button class="pause mt-3 px-4 btn btn-warning" style="display: none">PAUSE</button>
<button class="stop mt-3 px-4 btn btn-dark">STOP</button>
<button class="reset mt-3 px-4 btn btn-danger">RESET</button>
</div>
<p id="end" style="font-size:32px ;margin-top:30px;text-align:center"></p>
<div class="lap" style="text-align: center; font-size:16px;font-family: monospace;"></div>
</div>
</body>
</html>
BUG FIX!!!
I noticed the Start, Stop, Reset would not work if you hit Start more than once with the code above. I was able to fix this by tweaking the start function!
function start() {
if (timeBegan === null) {
timeBegan = new Date();
}else {
clearInterval(started);
};
if (timeStopped !== null) {
stoppedDuration += (new Date() - timeStopped);
};
if (stoppedDuration < 1000){
console.log(stoppedDuration+' ms');
};
if (stoppedDuration > 1000){
console.log(stoppedDuration/1000+' seconds');
};
started = setInterval(clockRunning, 10);
return stoppedDuration }
Related
I'm making a timer with jQuery. When you press the "Reset" button, it is supposed to make the "Start" button visible again.
I am getting this error:
Clicking the "Reset" button:
The selector "#reset" does not render the expected css for property "display": expected 'inline-block' to deeply equal 'none'
Here is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Interactivity</title>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="styles/site.css"/>
<script src="scripts/jquery-3.2.1.min.js"></script>
<script src="scripts/formatTime.js"></script>
<script src="scripts/times.js"></script>
<script src="scripts/reset.js"></script>
</head>
<body>
<div id="text">
<p>
Can you internally count 45 seconds precisely?
</p>
</div>
<button id="start">Start Timer</button>
<button id="stop" style="display: none;">Stop Timer</button>
<button id="reset" style="display: none;">Reset Timer</button>
<span id="time_started" class="hidden" style="display: none;">Timer Started</span>
<span id="time_ended" class="hidden">Timer Ended</span>
</body>
</html>
Here is my css:
body {
background-color: white;
font-family: sans-serif;
margin: 200px auto 0;
max-width: 900px;
}
h1 {
text-align: center;
}
div {
margin-bottom: 50px;
}
.hidden {
display: none;
}
Here is reset.js:
// reset everything
$("#reset").on('click',function() {
$(".results").addClass("hidden");
$("#reset").addClass("hidden");
$("#start").removeClass("hidden");
$("#time_started").addClass("hidden");
$("#time_ended").addClass("hidden");
});
Here is formatTime.js:
// formats the current date/time so that it reads as hh:mm:ss PM/AM
function formatTime(time) {
var
end_time,
formatted_time,
formatted_end_time,
start_time,
hour = 12,
minute = 10,
second = 10,
meridies;
hour = time.getHours();
if (hour>12) {
hour = hour-12;
meridies = "PM";
} else {
meridies = "AM";
}
minute = time.getMinutes();
if (minute<10) {
minute = "0"+minute;
}
second = time.getSeconds();
if (second<10) {
second = "0"+second;
}
return hour+":"+minute+":"+second+" "+meridies;
}
Here is times.js:
/* global formatTime: true */
/* Please do not remove the comment above. */
// timer to calculate the starting and stopping clicks
var start_time;
var formatted_time;
var end_time;
var formatted_end_time;
var time_change;
$(document).ready(function() {
$("#start").on('click',function() {
$("#start").hide();
$("#stop").show();
$("#time_started").hide();
$("#time_ended").hide();
end_time = new Date();
start_time = new Date();
formatted_time = formatTime(start_time);
});
$("#stop").on('click',function() {
$("#stop").hide();
$("#reset").show();
$("#time_started").hide();
$("#time_ended").show();
end_time = new Date();
formatted_end_time = formatTime(end_time);
$("body").append("<p class='results'>You started at "+formatted_time+".</p>");
$("body").append("<p class='results'>You finished at "+formatted_end_time+".</p>");
time_change = end_time-start_time;
$("body").append("<p class='results'>You counted "+(time_change/1000)+" seconds.</p>");
$("body").append("<p class='results'>You are off by "+(time_change/1000-45)+" seconds.</p>");
});
});
Avoid mixing addClass() / removeClass() vs hide() / show().
It should be obvious what addClass() / removeClass() do. hide() / show() add and remove inline css styles to achieve a similar end result (but inline styles will always take precedence).
$(function() {
$("#reset").on("click", function() {
$(".results").remove();
$("#reset").addClass("hidden");
$("#time_ended").addClass("hidden");
$("#start").removeClass("hidden");
});
// timer to calculate the starting and stopping clicks
var start_time;
var formatted_time;
var end_time;
var formatted_end_time;
var time_change;
$("#start").on("click", function() {
$("#start").addClass("hidden");
$("#stop").removeClass("hidden");
$("#time_started").removeClass("hidden");
$("#time_ended").addClass("hidden");
end_time = new Date();
start_time = new Date();
formatted_time = formatTime(start_time);
});
$("#stop").on("click", function() {
// $("#stop").hide();
$("#stop").addClass("hidden");
// $("#reset").show();
$("#reset").removeClass("hidden");
// $("#time_started").hide();
$("#time_started").addClass("hidden");
// $("#time_ended").show();
$("#time_ended").removeClass("hidden");
end_time = new Date();
formatted_end_time = formatTime(end_time);
$("body").append(
"<p class='results'>You started at " + formatted_time + ".</p>"
);
$("body").append(
"<p class='results'>You finished at " + formatted_end_time + ".</p>"
);
time_change = end_time - start_time;
$("body").append(
"<p class='results'>You counted " + time_change / 1000 + " seconds.</p>"
);
$("body").append(
"<p class='results'>You are off by " +
(time_change / 1000 - 45) +
" seconds.</p>"
);
});
});
function formatTime(time) {
var end_time,
formatted_time,
formatted_end_time,
start_time,
hour = 12,
minute = 10,
second = 10,
meridies;
hour = time.getHours();
if (hour > 12) {
hour = hour - 12;
meridies = "PM";
} else {
meridies = "AM";
}
minute = time.getMinutes();
if (minute < 10) {
minute = "0" + minute;
}
second = time.getSeconds();
if (second < 10) {
second = "0" + second;
}
return hour + ":" + minute + ":" + second + " " + meridies;
}
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="text">
<p>
Can you internally count 45 seconds precisely?
</p>
</div>
<button id="start">Start Timer</button>
<button id="stop" class="hidden">Stop Timer</button>
<button id="reset" class="hidden">Reset Timer</button>
<span id="time_started" class="hidden">Timer Started</span>
<span id="time_ended" class="hidden">Timer Ended</span>
Also, be careful when appending new content on every round and then just hiding it at the end (instead of actually removing it). You would end up with unnecessarily duplicated html.
Alternatively you could add the .results in the starting html with a class of .hidden to use the same hide/show method for everything.
$(function() {
$("#reset").on("click", function() {
$(".results").addClass("hidden");
$("#reset").addClass("hidden");
$("#time_ended").addClass("hidden");
$("#start").removeClass("hidden");
});
// timer to calculate the starting and stopping clicks
var start_time;
var formatted_time;
var end_time;
var formatted_end_time;
var time_change;
$("#start").on("click", function() {
$("#start").addClass("hidden");
$("#stop").removeClass("hidden");
$("#time_started").removeClass("hidden");
$("#time_ended").addClass("hidden");
end_time = new Date();
start_time = new Date();
formatted_time = formatTime(start_time);
});
$("#stop").on("click", function() {
$("#stop").addClass("hidden");
$("#reset").removeClass("hidden");
$("#time_started").addClass("hidden");
$("#time_ended").removeClass("hidden");
$(".results").removeClass("hidden");
end_time = new Date();
formatted_end_time = formatTime(end_time);
time_change = end_time - start_time;
$('#results-time-started span').text(formatted_time);
$('#results-time-ended span').text(formatted_end_time);
$('#results-time-counted span').text(time_change / 1000);
$('#results-time-off-by span').text(time_change / 1000 - 45);
});
});
function formatTime(time) {
var end_time,
formatted_time,
formatted_end_time,
start_time,
hour = 12,
minute = 10,
second = 10,
meridies;
hour = time.getHours();
if (hour > 12) {
hour = hour - 12;
meridies = "PM";
} else {
meridies = "AM";
}
minute = time.getMinutes();
if (minute < 10) {
minute = "0" + minute;
}
second = time.getSeconds();
if (second < 10) {
second = "0" + second;
}
return hour + ":" + minute + ":" + second + " " + meridies;
}
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="text">
<p>
Can you internally count 45 seconds precisely?
</p>
</div>
<button id="start">Start Timer</button>
<button id="stop" class="hidden">Stop Timer</button>
<button id="reset" class="hidden">Reset Timer</button>
<span id="time_started" class="hidden">Timer Started</span>
<span id="time_ended" class="hidden">Timer Ended</span>
<p id='results-time-started' class='hidden results'>You started at <span></span>.</p>
<p id='results-time-ended' class='hidden results'>You finised at <span></span>.</p>
<p id='results-time-counted' class='hidden results'>You counted <span></span> seconds.</p>
<p id='results-time-off-by' class='hidden results'>You are off by <span></span> seconds.</p>
So i want to make a program that start countingdown from a value that you choose but the issue is when i try to bring the value to javascript it dosen't work but when i type the value in html it work
here is my html code
<body>
<div id="count">
<input id="time" type="number" min="0">
<button id="button">Press here to begin the countdown</button>
</div>
<script src="lol.js"></script>
and here is my javascript code
var count = document.getElementById("count"),
seconds = document.getElementById("time").value ,
btn = document.getElementById("button"),
secondPass;
countDown = setInterval(function() {
secondPass()
} , 1000);
btn.onclick =
function secondPass(){
var minutes = Math.floor(seconds / 60),
remseconds = seconds % 60;
count.innerHTML = minutes + ":" + remseconds;
if (remseconds < 10){
remseconds = "0" + remseconds;
}
if (seconds> 0 ){
seconds = seconds - 1;
}
else {
clearInterval(countDown)
count.innerHTML = "done !"
}
}
The problem in your code was that you were trying to get the value before it was entered.
If I understood correctly, you wanted this:
var count = document.getElementById("count"),
btn = document.getElementById("button"),
secondPass;
btn.addEventListener("click", secondPass);
function secondPass() {
var seconds = document.getElementById("time").value
var countDown = setInterval(function () {
var minutes = Math.floor(seconds / 60),
remseconds = seconds % 60;
count.innerHTML = minutes + ":" + remseconds;
if (remseconds < 10) {
remseconds = "0" + remseconds;
}
if (seconds > 0) {
seconds = seconds - 1;
}
else {
clearInterval(countDown)
count.innerHTML = "done !"
}
}, 1000);
}
<div id="count">
<input id="time" type="number" min="0">
<button id="button">Press here to begin the countdown</button>
</div>
Main mistake - on time when you declare seconds variable - time input is empty.
I fixed your example, so you can figure out what was wrong
var count = document.getElementById("count"),
seconds,
btn = document.getElementById("button"),
countDown
btn.onclick = function() {
seconds = document.getElementById("time").value;
countDown = setInterval(function() {
secondPass()
}, 1000);
}
function secondPass(){
console.log('S', seconds)
var minutes = Math.floor(seconds / 60),
remseconds = seconds % 60;
count.innerHTML = minutes + ":" + remseconds;
if (remseconds < 10){
remseconds = "0" + remseconds;
}
if (seconds> 0 ){
seconds = seconds - 1;
}
else {
clearInterval(countDown)
count.innerHTML = "done !"
}
}
I have a page with timers. the code for my latest timer only functions properly. but the rest of the timers don't such as the 10 minute timer. It only shows you the set time for the timer. Is my latest code overriding my other code? Are variables being mixed between the two timers? I'm planning on adding several timers to the page, but I got stuck when this happened.
Link to code: http://jsfiddle.net/vtoLx02j/2/
<body>
<div id="1Div">
<h4>Question goes here?</h4>
<input type="text"id="name1"/>
<button onclick="myFunction1()" id="button0" class="button3">Enter</button>
</div>
<div id="2Div" style="display:none;">
<h4 id=typeE>How much time do you think you need in minutes?</h4>
<button onclick="myFunction2()" id="button1" class="button3">10 minutes</button>
<button onclick="myFunction3()" id="button2" class="button3">20 minutes</button>
</div>
<script>
function myFunction1(){
document.getElementById("1Div").style.display="none";
document.getElementById("2Div").style.display="block";
}
</script>
<script>
function myFunction2(){
document.getElementById("2Div").style.display="none";
document.getElementById("timer10").style.display="block";
}
</script>
<script>
function myFunction3(){
document.getElementById("2Div").style.display="none";
document.getElementById("timer20").style.display="block";
}
</script>
<div id="timer10" style="display:none">
<script>
function startTimer10(duration10, display10) {
var timer10 = duration10, minutes10, seconds10;
setInterval(function () {
minutes10 = parseInt(timer10 / 60, 10);
seconds10 = parseInt(timer10 % 60, 10);
minutes10 = minutes10 < 10 ? "0" + minutes10 : minutes10;
seconds10 = seconds10 < 10 ? "0" + seconds10 : seconds10;
display10.textContent = minutes10 + ":" + seconds10;
if (--timer10 < 0) {
timer10 = duration10;
}
}, 1000);
}
window.onload = function () {
var tenMinutes = 60 * 10,
display10 = document.querySelector('#time10');
startTimer10(tenMinutes, display10);
};
</script>
<body>
<center><div><span id="time10">10:00</span></div></center>
</body>
</div>
<div id="timer20" style="display:none">
<script>
function startTimer20(duration20, display20) {
var timer20 = duration20, minutes20, seconds20;
setInterval(function () {
minutes20 = parseInt(timer20 / 60, 10);
seconds20 = parseInt(timer20 % 60, 10);
minutes20 = minutes20 < 10 ? "0" + minutes20 : minutes20;
seconds20 = seconds20 < 10 ? "0" + seconds20 : seconds20;
display20.textContent = minutes20 + ":" + seconds20;
if (--timer20 < 0) {
timer20 = duration20;
}
}, 1000);
}
window.onload = function () {
var twentyMinutes = 60 * 20,
display20 = document.querySelector('#time20');
startTimer20(twentyMinutes, display20);
};
</script>
<body>
<center><div><span id="time20">20:00</span></div></center>
</body>
</div>
</body>
You can simply combine all your functions into single startTimer() function.
I am not sure why you are repeating your code again and again to achieve the same results. Its good to have less code but have the same results.
So here's is what i have done and simplified your code.
I have combined both timers into one function
You do not need to use display none and block again on show time duration
When you click on the timer just pass the minutes to the timer function and the span will start displaying the time remaining
You do no need two span to display timer separately you can do all that in one span
You were using script tag so many times which are unnecessary
Both timers are working perfectly with less code and same results.
You can have multiple timers now you just need to pass the minutes to your startTimer() function and timer will start from the given time.
Live Demo
//Start timer
function startTimer(duration, display) {
var timer = duration,
minutes, seconds;
setInterval(function() {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
//1
function myFunction1() {
document.getElementById("1Div").style.display = "none";
document.getElementById("2Div").style.display = "block";
}
//10 Minutes
function myFunction2() {
document.getElementById("2Div").style.display = "none";
var tenMinutes = 60 * 10,
display10 = document.querySelector('#timerDuration');
startTimer(tenMinutes, display10);
}
//20 minutes
function myFunction3() {
document.getElementById("2Div").style.display = "none";
var twentyMinutes = 60 * 20,
display20 = document.querySelector('#timerDuration');
startTimer(twentyMinutes, display20);
}
<body>
<div id="1Div">
<h4>Question goes here?</h4>
<input type="text" id="name1" />
<button onclick="myFunction1()" id="button0" class="button3">Enter</button>
</div>
<div id="2Div" style="display:none;">
<h4 id=typeE>How much time do you think you need in minutes?</h4>
<button onclick="myFunction2()" id="button1" class="button3">10 minutes</button>
<button onclick="myFunction3()" id="button2" class="button3">20 minutes</button>
</div>
<center>
<div><span id="timerDuration"></span></div>
</center>
</body>
I am building a pomodoro clock/countdown, but have an issue with formatting selected time to minutes/hours/seconds. I have tried to multiply the secs variable with 60 (secs*=60), but it makes a mess and I can't figure out how to fix it. So, I would like it to "know" that it needs to count down from 25 minutes - in 25:00 format, or more/less(hh:mm:ss) if the user chooses so with + and - buttons. All help very appreciated
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<h1 id="num">25 min</h1>
<div id="status"></div>
<button onclick='countDown(secs, "status")'>Start countdown</button>
<button onclick='increaseNumber()'>+</button>
<button onclick='decreaseNumber()'>-</button>
<script src="script.js"></script>
</body>
</html>
and here is javascript:
var num = document.getElementById('num').innerHTML;
var secs = parseInt(num);
function countDown(secs, elem) {
var element = document.getElementById(elem);
secs--;
var timer = setTimeout(function() {
countDown(secs, elem);
}, 1000);
//secs *= 60;
if(secs%60 >= 10){ //10 - if it's not a single digit number
document.getElementById('num').innerHTML = (Math.floor(secs/60) + ":" + secs%60);
}
else{
document.getElementById('num').innerHTML = (Math.floor(secs/60) + ":" + "0" + secs%60);
}
element.innerHTML = "Please wait for "+secs+" minutes";
//if timer goes into negative numbers
if(secs < 1){
clearTimeout(timer);
element.innerHTML = '<h2>Countdown complete!</h2>';
element.innerHTML += 'Click here now';
}
}
function increaseNumber() {
secs += 5;
document.getElementById('num').innerHTML = secs + ' min';
}
function decreaseNumber() {
if(secs >= 10) {
secs -= 5;
document.getElementById('num').innerHTML = secs + ' min';
}
}
Is there a reason you're doing it by hand ?
If you don't mind using a library, moment.js does a very good job at time manipulations. It's lightweight and very easy to use.
If you have to do it by hand because of some limitations, what are they ?
For reference:
//Creates a moment. Its value is the time of creation
var timer = moment();
//add 60 seconds to the timer
timer.add(60, 's');
//Removes 1 minutes from the timer
timer.subtract(1, 'm');
Sources :
Add
Substract
Try this countDown function:
function countDown(secs, elem) {
var element = document.getElementById(elem);
element.innerHTML = "Please wait for "+secs+" minutes";
var second = 0;
var timer = setInterval(function(){
var extraZero = second < 10 ? '0' : '';
document.getElementById('num').innerHTML = secs + ":" + extraZero + second;
if (second-- === 0) {
second = 59;
if (secs-- === 0){
clearInterval(timer);
element.innerHTML = '<h2>Countdown complete!</h2>';
element.innerHTML += 'Click here now';
}
}
}, 1000);
}
Since you are counting down the seconds, it is making more sense to use setInterval instead of setTimeout.
I'm working on a stopwatch, and this is my code for it. It makes perfect sense for me, but doesn't want to update for some reason.
HTML:
<ul>
<li id="hour">0</li>
<li>:</li>
<li id="min">0</li>
<li>:</li>
<li id="sec">0</li>
</ul>
JS:
var sec = document.getElementById("sec").value,
min = document.getElementById("min").value,
hour = document.getElementById("hour").value;
function stopWatch(){
sec++;
if(sec > 59) {
sec = 0;
min++;
} else if(min > 59){
min = 0;
hour++;
}
window.setTimeout("stopWatch()", 1000);
}
stopWatch();
A list item has no .value property. Inputs or textareas have. It should be
var sec = parseInt(document.getElementById("sec").innerHTML, 10),
min = parseInt(document.getElementById("min").innerHTML, 10),
hour = parseInt(document.getElementById("hour").innerHTML, 10);
which is also parsing them into numbers.
Also, don't pass a string to setTimeout. Pass the function you want to be called:
window.setTimeout(stopWatch, 1000);
And nowhere in your code you are outputting the updated variables. They are no magic pointers to the DOM properties, but just hold numbers (or strings in your original script).
Last but not least there's a logic error in your code. You are checking whether the minutes exceed 59 only when the seconds didn't. Remove that else before the if.
1) List items LI don't have values, they have innerHTML.
var sec = document.getElementById("sec").innerHTML; (not .value)
2) Nowhere in your code do you set the contents of your LIs. JavaScript doesn't magically associate IDs with variables - you have to do that bit yourself.
Such as:
document.getElementById("hour").innerHTML = hour;
3) Never pass a timeout as a string. Use an anonymous function:
window.setTimeout(function() {stopWatch()}, 1000);
or, plainly:
window.setTimeout(stopWatch, 1000);
(function() {
var sec = document.getElementById("sec").value,
min = document.getElementById("min").value,
hour = document.getElementById("hour").value;
function stopWatch(){
sec++;
if(sec > 59) {
sec = 0;
min++;
} else if(min > 59){
min = 0;
hour++;
}
document.getElementById("sec").textContent = sec
document.getElementById("min").textContent = min
document.getElementById("hour").textContent = hour
window.setTimeout(stopWatch, 1000);
}
stopWatch();
})();
The invocation should only be
window.setInterval(stopWatch, 1000);
So to use the stopwatch, put the function inside:
var sec = 0, min = 0, hour = 0;
window.setInterval(function () {
"use strict";
sec++;
if (sec > 59) {
sec = 0;
min++;
} else if (min > 59) {
min = 0;
hour++;
}
document.getElementById("sec").innerHTML = sec;
document.getElementById("min").innerHTML = hour;
document.getElementById("hour").innerHTML = hour;
}, 1000);
Li elements has no value propertie, use innerHTML.
You could store the values for sec, min & hour in variables.
It is a nice idea to store the setTimeout() call to a variable in case you want to stop the clock later. Like "pause".
http://jsfiddle.net/chepe263/A3a9m/4/
<html>
<head>
<style type="text/css">
ul li{
float: left;
list-style-type: none !important;
}
</style>
<script type="text/javascript">//<![CDATA[
window.onload=function(){
var sec = min = hour = 0;
var clock = 0;
stopWatch = function(){
clearTimeout(clock);
sec++;
if (sec >=59){
sec = 0;
min++;
}
if (min>=59){
min=0;
hour++;
}
document.getElementById("sec").innerHTML = (sec < 10) ? "0" + sec : sec;
document.getElementById("min").innerHTML = (min < 10) ? "0" + min : min;
document.getElementById("hour").innerHTML = (hour < 10) ? "0" + hour : hour;
clock = setTimeout("stopWatch()",1000); }
stopWatch();
pause = function(){
clearTimeout(clock);
return false;
}
play = function(){
stopWatch();
return false;
}
reset = function(){
sec = min = hour = 0;
stopWatch();
return false;
}
}//]]>
</script>
</head>
<body>
<ul>
<li id="hour">00</li>
<li>:</li>
<li id="min">00</li>
<li>:</li>
<li id="sec">49</li>
</ul>
<hr />
Pause
Continue
Reset
</body>
</html>
This is my complete code, this may help you out:
<html>
<head>
<title>Stopwatch Application ( Using JAVASCRIPT + HTML + CSS )</title>
<script language="JavaScript" type="text/javascript">
var theResult = "";
window.onload=function() { document.getElementById('morefeature').style.display = 'none'; }
function stopwatch(text) {
var d = new Date(); var h = d.getHours(); var m = d.getMinutes(); var s = d.getSeconds(); var ms = d.getMilliseconds();
document.stopwatchclock.stpwtch.value = + h + " : " + m + " : " + s + " : " + ms;
if (text == "Start") {
document.stopwatchclock.theButton.value = "Stop";
document.stopwatchclock.theButton.title = "The 'STOP' button will save the current stopwatch time in the stopwatch history, halt the stopwatch, and export the history as JSON object. A stopped stpwatch cannot be started again.";
document.getElementById('morefeature').style.display = 'block';
}
if (text == "Stop") {
var jsnResult = arrAdd();
var cnt = 0; var op= 'jeson output';
for (var i = 0; i < jsnResult.length; i++) {
if (arr[i] !== undefined) {
++cnt; /*json process*/
var j={ Record : cnt, Time : arr[i]};
var dq='"';
var json="{";
var last=Object.keys(j).length;
var count=0;
for(x in j){ json += dq+x+dq+":"+dq+j[x]+dq; count++;
if(count<last)json +=",";
}
json+="}<br>";
document.write(json);
}
}
}
if (document.stopwatchclock.theButton.value == "Start") { return true; }
SD=window.setTimeout("stopwatch();", 100);
theResult = document.stopwatchclock.stpwtch.value;
document.stopwatchclock.stpwtch.title = "Start with current time with the format (hours:mins:secs.milliseconds)" ;
}
function resetIt() {
if (document.stopwatchclock.theButton.value == "Stop") { document.stopwatchclock.theButton.value = "Start"; }
window.clearTimeout(SD);
}
function saveIt() {
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value; value++;
document.getElementById('number').value = value;
var resultTitle = '';
if(value == '1'){ resultTitle = "<h3>History</h3><hr color='black'>"; }
var objTo = document.getElementById('stopwatchresult')
var spanTag = document.createElement("span");
spanTag.id = "span"+value;
spanTag.className ="stopWatchClass";
spanTag.title ="The stopwatch showing current stopwatch time and a history of saved times. Each saved time are shown as total duration (split time - stopwatch start time) and a lap duration (split time - previous split time). And durations are shown in this format: 'hours:mins:secs.milliseconds'";
spanTag.innerHTML = resultTitle +"<br/><b>Record " + value+" =</b> " + theResult + "";
objTo.appendChild(spanTag);
arrAdd(theResult);
return;
}
var arr = Array();
function arrAdd(value){ arr.push(value); return arr;}
</script>
<style>
center {
width: 50%;
margin-left: 25%;
}
.mainblock {
background-color: #07c1cc;
}
.stopWatchClass {
background-color: #07c1cc;
display: block;
}
#stopwatchclock input {
margin-bottom: 10px;
width: 120px;
}
</style>
</head>
<body>
<center>
<div class="mainblock">
<h1><b title="Stopwatch Application ( Using JAVASCRIPT + HTML + CSS )">Stopwatch Application</b></h1>
<form name="stopwatchclock" id="stopwatchclock">
<input type="text" size="16" class="" name="stpwtch" value=" 00 : 00 : 00 : 00" title="Initially blank" />
<input type="button" name="theButton" id="start" onClick="stopwatch(this.value);" value="Start" title="The 'START' button is start the stopwatch. An already started stopwatch cannot be started again." /><br />
<div id="morefeature">
<input type="button" value="Reset" id="resetme" onClick="resetIt();reset();" title="Once you will click on 'RESET' button will entirely reset the stopwatch so that it can be started again." />
<input type="button" name="saver" id="split" value="SPLIT" onClick="saveIt();" title="The 'SPLIT' button will save the current stopwatch time in the stopwatch history. The stopwatch will continue to progress after split." />
<div>
<input type="hidden" name="number" id="number" value="0" />
</form>
</div>
<div id="stopwatchresult"></div>
</center>
</body>