I've got a timer function as follows (which I've just grabbed off a jsfiddle):
function countdown( elementName, minutes, seconds )
{
var element, endTime, hours, mins, msLeft, time;
function returnDate(){
return Number(new Date);
}
function twoDigits( n )
{
return (n <= 9 ? "0" + n : n);
}
function updateTimer()
{
msLeft = endTime - (returnDate());
if ( msLeft < 1000 ) {
element.innerHTML = "0:00";
} else {
time = new Date( msLeft );
hours = time.getUTCHours();
mins = time.getUTCMinutes();
element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) + ':' + twoDigits( time.getUTCSeconds() );
setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
}
}
element = document.getElementById( elementName );
endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
updateTimer();
}
I call the function and set it to countdown to 2 minutes like so:
$(".btn-start").click(function(){
countdown("countdown-2-minutes",2,0);
});
I have another element with id countdown-8-minutes that I want to start immediately when the timer on countdown-2-minutes reaches 0. How should I do this? I suppose an okay way would be to monitor when the html on the first element reads "0:00" but I don't exactly know how to implement that.
Here's what I would suggest; First change your countdown() function to accept a callback parameter:
function countdown( elementName, minutes, seconds, callback )
{
var element, endTime, hours, mins, msLeft, time;
function returnDate(){
return Number(new Date);
}
function twoDigits( n )
{
return (n <= 9 ? "0" + n : n);
}
function updateTimer()
{
msLeft = endTime - (returnDate());
if ( msLeft < 1000 ) {
element.innerHTML = "0:00";
if (typeof callback === 'function') {
callback.call()
}
} else {
time = new Date( msLeft );
hours = time.getUTCHours();
mins = time.getUTCMinutes();
element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) + ':' + twoDigits( time.getUTCSeconds() );
setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
}
}
element = document.getElementById( elementName );
endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
updateTimer();
}
then pass that callback with your initial call:
$(".btn-start").click(function(){
countdown("countdown-2-minutes",2,0, function(){countdown("countdown-8-minutes",8,0);});
});
Just call countdown() with the proper parameters when you detect that the timer is finished. Try this:
if ( msLeft < 1000 ) {
element.innerHTML = "0:00";
countdown("countdown-8-minutes",8,0);
}
You don't need to watch the element's content to know when to start the next timer. In fact you're already reacting to that happening on the line you check if ( msLeft < 1000 ) { in which you can start your next timer.
Once your current timer hits zero you can just start the next one inside that if statement.
Alternatively you can separate your timer logic from your element logic using something like this:
// CountdownTimer object. Give it a length (ms) to count to, a period (ms)
// to loop updates to the callback, and a callback (function(done:bool)) that
// handles update ticks where done=false and the final tick where done=true.
function CountdownTimer(length, period, callback) {
this.length = length;
this.period = period;
this.callback = callback;
// Assert the callback to be a function to avoid messy error handling, and
// show we noticed in the console.
if (typeof this.callback !== 'function') {
console.warn('Callback was not a function.');
this.callback = function(){};
}
// Some publically visible variables for time keeping.
this.startTime = 0;
this.elapsed = 0;
this.remaining = length;
// The _loop scope's 'this' is itself. Give it a handle on the CountdownTimer's
// 'this' so we can reference the variables inside the loop.
var scope = this;
// Main loop of the countdown timer.
this._loop = function() {
// Get the number of milliseconds since the countdown started.
scope.elapsed = Date.now() - scope.startTime;
if (scope.elapsed < scope.length) {
// Keep looping if the countdown is not yet finished.
scope.remaining = scope.length - scope.elapsed;
scope.callback(false);
} else {
// Finished looping when the countdown hits or passes the target.
scope.elapsed = scope.length;
scope.remaining = 0;
scope.callback(true);
// Stop the interval timer from looping again.
clearInterval(scope._t);
}
};
}
// This function starts up the CountdownTimer
CountdownTimer.prototype.start = function() {
this.startTime = Date.now();
this._t = setInterval(this._loop, this.period);
}
// Our test elements.
var progress2 = document.getElementById('prog-2m');
var progress8 = document.getElementById('prog-8m');
var clockElement = document.getElementById('clock');
var startButton = document.getElementById('start');
// The 2-minute timer.
var m2 = new CountdownTimer(2 * 60 * 1000, 33, function(done) {
// Calculate the time to display.
var mins = Math.floor(m2.remaining / 60 / 1000);
var secs = Math.floor(m2.remaining / 1000) % 60;
if (secs < 10) secs = '0' + secs;
clockElement.textContent = mins + ':' + secs;
if (done) {
// If we're done, set the timer to show zero and start the next timer.
clockElement.textContent = '0:00';
m8.start();
}
// Progress bar display update.
progress2.style.width = (40 * (m2.elapsed / m2.length)) + 'px';
progress8.style.width = (160 * (m8.elapsed / m8.length)) + 'px';
});
// The 8-minute timer.
var m8 = new CountdownTimer(8 * 60 * 1000, 33, function(done) {
// Calculate the time to display.
var mins = Math.floor(m8.remaining / 60 / 1000);
var secs = Math.floor(m8.remaining / 1000) % 60;
if (secs < 10) secs = '0' + secs;
clockElement.textContent = mins + ':' + secs;
if (done) {
// Once done, set the timer to zero and display "Done".
clockElement.textContent = '0:00 Done';
}
// Progress bar display update.
progress2.style.width = (40 * (m2.elapsed / m2.length)) + 'px';
progress8.style.width = (160 * (m8.elapsed / m8.length)) + 'px';
});
// Start the 2-minute timer when the button is clicked.
startButton.addEventListener('click', function() {
m2.start();
});
#progress {
width: 200px;
height: 20px;
border: 2px solid #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
border-radius: 2px;
position: relative;
margin: 8px 0;
}
#prog-2m {
width: 40px;
height: 20px;
background-color: #3c9;
position: absolute;
left: 0;
top: 0;
}
#prog-8m {
width: 160px;
height: 20px;
background-color: #c33;
position: absolute;
left: 40px;
top: 0;
}
<div id="progress">
<div id="prog-2m"></div>
<div id="prog-8m"></div>
</div>
<div id="clock">0:00</div>
<button id="start">Begin</button>
Related
I have a JavaScript stopwatch here, I require the start-stop button to keep the same time when continuing.
Currently, if I stop and continue the clock diff is something ridiculous such as '-19330839:-3:-53'
Can anyone explain how this is fixed?
I have various method stopwatches made; however I would rather use real date time instead of a counter, this is because (I have tested after being made aware of this) that counters are very inaccurate over a period of time.
Any help is much appreciated.
html:
Please ignore the reset button for now. I will configure this later.
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" value="Start" onclick="startstop();">
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst1" id='btnRst1' value="Reset" onclick="resetclock();"/>
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>
JS:
const outputElement = document.getElementById("outputt");
var startTime = 0;
var running = false;
var splitcounter = 0;
function startstop() {
if (running == false) {
running = true;
startTime = new Date(sessionStorage.getItem("time"))
if (isNaN(startTime)) startTime = Date.now();
startstopbutton.value = 'Stop';
document.getElementById("outputt").style.backgroundColor = "#2DB37B";
updateTimer();
} else {
running = false;
logTime();
startstopbutton.value = 'Start';
document.getElementById("outputt").style.backgroundColor = "#B3321B";
}
}
function updateTimer() {
if (running == true) {
let differenceInMillis = Date.now() - startTime;
sessionStorage.setItem("time", differenceInMillis)
let {
hours,
minutes,
seconds
} = calculateTime(differenceInMillis);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
requestAnimationFrame(updateTimer);
}
}
function calculateTime(milliS) {
const SECONDS = 1000; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;
let hours = Math.floor(milliS / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(milliS / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(milliS / SECONDS) % RESET;
return {
hours,
minutes,
seconds
};
}
function pad(time) {
return time.toString().padStart(2, '0');
}
I just need the timer to continue on from where it was stopped at.
Issue with your code:
You start with initial value for sessionStorage as Date.now but then save difference on update.
You interact a lot with session storage. Any communication with external API is expensive. Instead use local variables and find an event to initialise values.
Time difference logic is a bit off.
Date.now - startTime does not considers the difference between stop action and start action.
You can use this logic: If startTime is defined, calculate difference and add it to start time. If not, initialise it to Date.now()
Suggestions:
Instead of adding styles, use classes. That will help you in reset functionality
Define small features and based on it, define small functions. That would make reusability easy
Try to make functions independent by passing arguments and only rely on them. That way you'll reduce side-effect
Note: as SO does not allow access to Session Storage, I have removed all the related code.
const outputElement = document.getElementById("outputt");
var running = false;
var splitcounter = 0;
var lastTime = 0;
var startTime = 0;
function logTime() {
console.log('Time: ', lastTime)
}
function resetclock() {
running = false;
startTime = 0;
printTime(Date.now())
applyStyles(true)
}
function applyStyles(isReset) {
startstopbutton.value = running ? 'Stop' : 'Start';
document.getElementById("outputt").classList.remove('red', 'green')
if (!isReset) {
document.getElementById("outputt").classList.add(running ? 'red' : 'green')
}
}
function startstop() {
running = !running;
applyStyles();
if (running) {
if (startTime) {
const diff = Date.now() - lastTime;
startTime = startTime + diff;
} else {
startTime = Date.now()
}
updateTimer(startTime);
} else {
lastTime = Date.now()
logTime();
}
}
function printTime(startTime) {
let differenceInMillis = Date.now() - startTime;
let {
hours,
minutes,
seconds
} = calculateTime(differenceInMillis);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
}
function updateTimer(startTime) {
if (running == true) {
printTime(startTime)
requestAnimationFrame(() => updateTimer(startTime));
}
}
function calculateTime(milliS) {
const SECONDS = 1000; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;
let hours = Math.floor(milliS / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(milliS / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(milliS / SECONDS) % RESET;
return {
hours,
minutes,
seconds
};
}
function pad(time) {
return time.toString().padStart(2, '0');
}
.red {
background-color: #2DB37B
}
.green {
background-color: #B3321B
}
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" value="Start" onclick="startstop();">
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst1" id='btnRst1' value="Reset" onclick="resetclock();" />
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>
simple stopwatch example
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input class="startstop" style="width: 120px;" type="button" value="Start" onclick="startstop();">
<input class="reset" style="width: 120px;" type="button" value="Reset" onclick="reset();"/>
<div class="timerClock" value="00:00:00">00:00:00</div>
<script type="text/javascript">
var second = 0
var minute = 0
var hour = 0
var interval
var status = false
var element = document.querySelector('.startstop')
var clock = document.querySelector('.timerClock')
var string = ''
function startstop()
{
if(status == 'false')
{
element.value = 'Stop'
clock.style.backgroundColor = "#2DB37B";
status = true
interval = setInterval(function()
{
string = ''
second += 1
if(second >= 60)
{
minute += 1
second = 0
}
if(minute >= 60)
{
hour += 1
minute = 0
}
if(hour < 10)
string += `0${hour}:`
else
string += `${hour}:`
if(minute < 10)
string += `0${minute}:`
else
string += `${minute}:`
if(second < 10)
string += `0${second}`
else
string += `${second}`
clock.innerHTML = string
},1000)
}
else
{
clock.style.backgroundColor = "#B3321B";
element.value = 'Start'
status = false
clearInterval(interval)
}
}
function reset()
{
second = 0
minute = 0
hour = 0
status = false
element.value = 'Start'
clearInterval(interval)
clock.innerHTML = `00:00:00`
clock.style.backgroundColor = "transparent";
}
</script>
</body>
</html>
One thing to know about requestAnimationFrame is that it returns an integer that is a reference to the next animation. You can use this to cancel the next waiting animation with cancelAnimationFrame.
As mentioned by #Rajesh, you shouldn't store the time each update, as it will stop the current process for a (very) short while. Better in that case to fire an event, preferably each second, that will wait until it can run. I haven't updated the code to take that into account, I only commented it away for now.
It's also better to use classes than updating element styles. I wrote sloppy code that overwrites all classes on the #outputt element (it's spelled "output"). That's bad programming, because it makes it impossible to add other classes, but it serves the purpose for now. #Rajesh code is better written for this purpose.
I added two variables - diffTime and animationId. The first one corrects startTime if the user pauses. The second one keeps track if there is an ongoing timer animation.
I refactored your style updates into a method of its own. You should check it out, because it defines standard values and then changes them with an if statement. It's less code than having to type document.getElementById("outputt").style... on different rows.
I also added a resetclock method.
const outputElement = document.getElementById("outputt");
var startTime = 0;
var diffTime = 0;
var animationId = 0;
function startstop() {
const PAUSED = 0;
let paused = animationId == PAUSED;
//diffTime = new Date(sessionStorage.getItem("time")) || 0;
startTime = Date.now() - diffTime;
if (paused) {
updateTimer();
} else {
cancelAnimationFrame(animationId);
animationId = PAUSED;
}
updateTimerClass(paused);
}
function updateTimerClass(paused) {
var outputClass = 'red';
var buttonText = 'Start';
if (paused) {
outputClass = 'green';
buttonText = 'Stop';
}
startstopbutton.value = buttonText;
outputElement.classList = outputClass;
}
function updateTimer() {
let differenceInMillis = Date.now() - startTime;
//sessionStorage.setItem("time", differenceInMillis)
let {
hours,
minutes,
seconds
} = calculateTime(differenceInMillis);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
diffTime = differenceInMillis;
animationId = requestAnimationFrame(updateTimer);
}
function calculateTime(milliS) {
const SECONDS = 1000; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;
let hours = Math.floor(milliS / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(milliS / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(milliS / SECONDS) % RESET;
return {
hours,
minutes,
seconds
};
}
function pad(time) {
return time.toString().padStart(2, '0');
}
function resetclock() {
let paused = animationId == 0;
startTime = Date.now();
diffTime = 0;
if (paused) {
const REMOVE_ALL_CLASSES = '';
outputElement.className = REMOVE_ALL_CLASSES;
outputElement.innerText = '00:00:00';
}
}
#outputt.green {
background-color: #2DB37B;
}
#outputt.red {
background-color: #B3321B;
}
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" value="Start" onclick="startstop();">
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst1" id='btnRst1' value="Reset" onclick="resetclock();"/>
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>
class Stopwatch {
constructor(display, results) {
this.running = false;
this.display = display;
this.results = results;
this.laps = [];
this.reset();
this.print(this.times);
}
reset() {
this.times = [ 0, 0, 0 ];
}
click(){
var x=document.getElementById('ctrl');
if(x.value=="start"){
this.start();
x.value="stop";
document.getElementById("outputt").style.backgroundColor = "#2DB37B";
}
else{
x.value="start";
this.stop();
document.getElementById("outputt").style.backgroundColor = "#B3321B";
}
}
start() {
if (!this.time) this.time = performance.now();
if (!this.running) {
this.running = true;
requestAnimationFrame(this.step.bind(this));
}
}
stop() {
this.running = false;
this.time = null;
}
resets() {
document.getElementById("outputt").style.backgroundColor = "#2DB37B";
if (!this.time) this.time = performance.now();
if (!this.running) {
this.running = true;
requestAnimationFrame(this.step.bind(this));
}
this.reset();
}
step(timestamp) {
if (!this.running) return;
this.calculate(timestamp);
this.time = timestamp;
this.print();
requestAnimationFrame(this.step.bind(this));
}
calculate(timestamp) {
var diff = timestamp - this.time;
// Hundredths of a second are 100 ms
this.times[2] += diff / 1000;
// Seconds are 100 hundredths of a second
if (this.times[2] >= 100) {
this.times[1] += 1;
this.times[2] -= 100;
}
// Minutes are 60 seconds
if (this.times[1] >= 60) {
this.times[0] += 1;
this.times[1] -= 60;
}
}
print() {
this.display.innerText = this.format(this.times);
}
format(times) {
return `\
${pad0(times[0], 2)}:\
${pad0(times[1], 2)}:\
${pad0(Math.floor(times[2]), 2)}`;
}
}
function pad0(value, count) {
var result = value.toString();
for (; result.length < count; --count)
result = '0' + result;
return result;
}
function clearChildren(node) {
while (node.lastChild)
node.removeChild(node.lastChild);
}
let stopwatch = new Stopwatch(
document.querySelector('.stopwatch'),
document.querySelector('.results'));
<input type="button" id="ctrl" value="start" onClick="stopwatch.click();">
<input type="button" value="Reset" onClick="stopwatch.resets();">
<div id="outputt" class="stopwatch"></div>
I have made a countdown but now I want to make a input field with how many minutes the countdown should countdown from. What I have is a pretty basic countdown but what I don't have is that a user puts the amount of minutes into the input field, click the button, and it counts down the minutes. And I hope someone can help me with this.
This is what I got so far:
(()=> {
let countdownEnded = false;
start(3600); // seconds
})();
function start(inputTime){
let startTime = Date.now();
intervalSeconds = setInterval(() => {
let currentTime = Date.now() - startTime;
if(inputTime < 1) {
stop();
} else {
updateDisplay(inputTime, currentTime);
updateMillis();
}
}, 1000);
}
function stop(){
let countDivElement = document.getElementById("countdown"); /*** Updated***/
countDivElement.innerHTML = 'countdown done';
countdownEnded = true; /*** Updated***/
}
function updateDisplay(seconds, currentTime){
let timeIncrement = Math.floor(currentTime / 1000);
updateTime(seconds - timeIncrement);
}
/**
* #method - updatesecondsond
* #summary - This updates the timer every seconds
*/
function updateTime(seconds) {
let countDivElement = document.getElementById("timer");
let minutes = Math.floor(seconds / 60);
let remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = '0' + remainingSeconds;
}
if (minutes < 10) {
minutes = '0' + minutes;
}
if (seconds > 0) {
seconds = seconds - 1;
} else {
clearInterval(intervalSeconds);
countdownEnded = true;
countDivElement.innerHTML = 'countdown done';
return null;
}
countDivElement.innerHTML = minutes + ":" + remainingSeconds + ":" ;
};
function updateMillis() {
let countMillsElement = document.getElementById('millis');
let counterMillis = 99;
let millis;
let intervalMillis = setInterval(()=> {
if(counterMillis === 1) {
counterMillis = 99;
} else {
millis = counterMillis < 10 ? '0' + counterMillis : counterMillis;
};
countMillsElement.innerHTML = millis;
counterMillis --;
}, 10);
if(countdownEnded) {
stop(); /*** Updated***/
return clearInterval(intervalMillis);
}
};
<div class="clock" id="model3">
<div id="countdown"> <!-- Updated -->
<span id="timer"></span><span id="millis"></span>
</div>
</div>
<input id="minutes" placeholder="0:00"/>
I think this may help you.
Change the following
<input id="minutes" placeholder="00"/> <button onclick="startTimer()">Start</button>
And in javascript add a new function
function startTimer(){
var x=document.getElementById("minutes").value * 60; //To Change into Seconds
start(x);
}
And remove the start function
Just add a button with click event that takes input value and triggers your 'start' function with that value as parameter. Something like this:
document.getElementById("startBtn").addEventListener("click", startTimer);
function startTimer() {
var numberOfMinutes = Number(document.getElementById("minutes").value) * 60;
start(numberOfMinutes);
}
And remove 'start' function call from the window load to prevent the timer to start immidiately.
Result is something like this:
https://jsfiddle.net/scarabs/6patc9mo/1/
i've tried to make simple countdown timer, but i don't know how to make something when the timer ends and i don't know how to make timer with hours HH. I can make only minutes MM and second SS.
So, i have this HTML code:
<div class="tadc-time-display">
<span class="tadc-time-display-hours_minutes">00:00</span>
<span class="tadc-time-display-seconds">00</span>
</div>
The JS code i used to have is useless(
You can use Native JavaScript or jQuery, if you want)
function startTimer(duration, display) {
var start = Date.now(),
diff,
minutes,
seconds;
function timer() {
// get the number of seconds that have elapsed since
// startTimer() was called
diff = duration - (((Date.now() - start) / 1000) | 0);
// does the same job as parseInt truncates the float
minutes = (diff / 60) | 0;
seconds = (diff % 60) | 0;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (diff <= 0) {
// add one second so that the count down starts at the full duration
// example 05:00 not 04:59
start = Date.now() + 1000;
}
};
// we don't want to wait a full second before the timer starts
timer();
setInterval(timer, 1000);
}
window.onload = function () {
var fiveMinutes = 60 * 0.1,
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
It should also start, stop and reset, but i dont know how to do it( Thanks a lot!
var hours = 0, // obtain these values somewhere else
minutes = 1,
seconds = 20,
target = new Date(),
timerDiv = document.getElementById("timer"),
handler;
function init() {
// set the target date time with the counter values
// counters more then 24h should have a date setup or it wont work
target.setHours(hours);
target.setMinutes(minutes);
target.setSeconds(seconds);
target.setMilliseconds(0); // make sure that miliseconds is 0
timerDiv.innerHTML = target.toTimeString().split(" ")[0]; // print the value
}
function updateTimer() {
var time = target.getTime();
target.setTime(time - 1000); // subtract 1 second with every thick
timerDiv.innerHTML = target.toTimeString().split(" ")[0];
if (
target.getHours() === 0 &&
target.getMinutes() === 0 &&
target.getSeconds() === 0
) { // counter should stop
clearInterval(handler);
}
}
handler = setInterval(updateTimer, 1000);
document.getElementById("stop-button").addEventListener("click", function() {
clearInterval(handler);
});
document.getElementById("start-button").addEventListener("click", function() {
clearInterval(handler);
handler = setInterval(updateTimer, 1000);
});
document.getElementById("reset-button").addEventListener("click", function() {
init();
clearInterval(handler);
});
init();
<div id="timer"></div>
<div>
<button id="start-button">Start</button>
<button id="stop-button">Stop</button>
<button id="reset-button">Reset</button>
</div>
Here is working sample with comments.
try this :
<html lang="en"><head>
<style>
#import "//fonts.googleapis.com/css?family=Bangers";
body {
margin: 0;
}
.wrap {
display: flex;
align-items: center;
justify-content: center;
background:#111;
}
.time-to {
text-align: center;
font-family: Bangers;
color: white;
font-size: 50px;
}
.underline {
text-decoration: underline;
}
.time-to span {
display: block;
font-size: 70px;
}
</style>
<script>
window.console = window.console || function(t) {};
</script>
<script>
if (document.location.search.match(/type=embed/gi)) {
window.parent.postMessage("resize", "*");
}
</script>
</head>
<body translate="no">
<div class="wrap ng-scope" ng-app="app">
<div class="time-to">
prochain event dans :
<span countdown="" date="november 17, 2019 15:15:50" class="ng-isolate-scope underline"></span>
<br>
event : minecraft , ip: 144.76.116.78:40020
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script id="rendered-js">
(function () {
angular.module('app', []).directive('countdown', [
'Util',
'$interval',
function (Util,
$interval) {
return {
restrict: 'A',
scope: {
date: '#' },
link: function (scope,
element) {
var future;
future = new Date(scope.date);
$interval(function () {
var diff;
diff = Math.floor((future.getTime() - new Date().getTime()) / 1000);
return element.text(Util.dhms(diff));
},
1000);
} };
}]).
factory('Util', [
function () {
return {
dhms: function (t) {
var days,
hours,
minutes,
seconds;
if(t < 0) {
t = 0
}
if(t === 0) {
t = 0
}
days = Math.floor(t / 86400);
t -= days * 86400;
hours = Math.floor(t / 3600) % 24;
t -= hours * 3600;
minutes = Math.floor(t / 60) % 60;
t -= minutes * 60;
seconds = t % 60;
if(t < 0) {
t = 0
}
if(t === 0) {
t = 0
}
return [days + 'd',
hours + 'h',
minutes + 'm',
seconds + 's'].join(' ');
} };
}]);
}).call(this);
</script>
</body></html>
I have created this stopwatch and it runs pretty well. The only problem that I am having is that whenever I click my "stop" button, the time stops on the screen but it is still running in the background.
Is there any way to stop this from happening? I want the timer to stop on its current time, then when I click "start", it resumes from the time it was stopped on.
Im thinking maybe create a "new Date()" variable before the update function and another "new Date()" variable inside of the update function and somehow subtract those to get the current date. But I cannot figure that out either.
start = document.getElementById('Start');
stop = document.getElementById('Stop');
let watchRunning = false;
Start.addEventListener('click', startHandler);
Stop.addEventListener('click', stopHandler);
function startHandler() {
if (!watchRunning) {
watchRunning = setInterval(update, 70);
}
}
function stopHandler() {
clearInterval(watchRunning);
watchRunning = null;
}
update();
var seconds;
var milliseconds;
var d;
function update() {
d = new Date();
seconds = d.getSeconds();
milliseconds = Math.floor((d.getMilliseconds() / 10));
if (milliseconds < 10 && seconds < 10) {
document.getElementById("Time").innerHTML =
"0" + seconds + ".0" + milliseconds;
} else if (milliseconds < 10 && seconds >= 10) {
document.getElementById("Time").innerHTML =
seconds + ".0" + milliseconds;
} else if (milliseconds >= 0 && seconds < 10) {
document.getElementById("Time").innerHTML =
"0" + seconds + "." + milliseconds;
} else if (milliseconds >= 0 && seconds >= 10) {
document.getElementById("Time").innerHTML =
seconds + "." + milliseconds;
}
}
#Time {
background-color: yellow;
max-width: 2.3%;
}
<h1>Stop Watch</h1>
<button id="Start">Start</button>
<button id="Stop">Stop</button>
<h3>Elapsed Time:</h3>
<p id="Time"></p>
Try running the snippet and you will see what I mean. The time doesn't stop "running" after I click stop, and when I click start it resumes as if it was never stopped.
clearTimeout( return ID of setTimeout() );
clearTime variable is returned as a value by the setTimeout( ) timing method, which can be pass to the clearTimeout( ID ) as an ID to reference it - clearTimeout( clearTime );
How It Works
Whenever the clearTimeout( ) timing method is called on a setTimeout( ) timing method that is active, the clearTimeout( ) timing method will stop the execution of the setTimeout( ) timing method but without destroying its execution entirely.
The setTimeout( ) timing method is left idle during the period that the clearTimeout( ) timing method is called, and when you re-execute the setTimeout( ) timing method, it will start from the point its execution was stopped, not starting all over from the beginning.
You're good to go!
You should use a setInterval to run your code to update the stopwatch instead of relying on a Date; you can not stop the Date from changing, so even though you stopped updating your stopwatch, the seconds are still ticking by which makes it seem like your stopwatch never stopped.
#Time {
background-color: yellow;
max-width: 2.3%;
}
<h1>Stop Watch</h1>
<button id="Start">Start</button>
<button id="Stop">Stop</button>
<h3>Elapsed Time:</h3>
<p id="Time">00:00</p>
<script>
var start = document.getElementById('Start'), stop = document.getElementById('Stop'), time = document.getElementById('Time');
function StopWatch(props){
this.seconds = props.seconds||0;
this.milliseconds = props.milliseconds||0;
this.updateCallback = props.updateCallback;
this._running = false;
}
StopWatch.prototype = {
start: function(){
var _this = this;
if(!_this._running){
_this._running = true;
_this._intervalID = window.setInterval(function(){
if(++_this.milliseconds==100){
_this.seconds++;
_this.milliseconds = 0;
}
if(_this.updateCallback){
_this.updateCallback(_this.milliseconds, _this.seconds);
}
}, 10);
}
},
stop: function(){
window.clearInterval(this._intervalID);
this._running = false;
},
getTimeString: function(){
var ms = this.milliseconds, s = this.seconds;
if(ms<10){
ms = "0"+ms;
}
if(s<10){
s = "0"+s;
}
return s + ":" + ms;
}
}
var sw = new StopWatch({updateCallback: function(){
time.textContent = sw.getTimeString();
}});
start.addEventListener('click', function(){
sw.start();
});
stop.addEventListener('click', function(){
sw.stop();
});
</script>
I have some JavaScript with a countdown ticker, when it reaches 0 it displays the text "ended".
When this happens I need to display block on two divs and add a class to another div.
Here is the JS code:
function countdown( elementName, minutes, seconds )
{
var element, endTime, hours, mins, msLeft, time;
function twoDigits( n )
{
return (n <= 9 ? "0" + n : n);
}
function updateTimer()
{
msLeft = endTime - (+new Date);
if ( msLeft < 1000 ) {
element.innerHTML = "Ended";
} else {
time = new Date( msLeft );
hours = time.getUTCHours();
mins = time.getUTCMinutes();
element.innerHTML = (hours ? hours + 'h ' + twoDigits( mins ) : mins) + 'm ' + twoDigits( time.getUTCSeconds() + 's' );
setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
}
}
element = document.getElementById( elementName );
endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
updateTimer();
}
countdown( "countdown", 1, 5 );
countdown( "countdown2", 100, 0 );
HTML:
<div id="countdown"></div>
Here is a fiddle: https://jsfiddle.net/vek5808u/8/
Any help would be great
Thanks
inside the if block
if ( msLeft < 1000 ) {
document.querySelector(".messaging").style.display="block";
document.querySelector(".img-message").style.display="block";
document.querySelector(".img-container").className += " opacity-overlay";
element.innerHTML = "Ended";
}
https://jsfiddle.net/vek5808u/36/
There is a bit of delay between when the time starts and the time is displayed. You may need to play around with that, but the procedure is pretty simple.
I based the Countdown class on a Repeater class that someone created in another question.
I even wrapped it in a jQuery plugin for ease of use.
const twoDigits = n => n <= 9 ? '0' + n : n;
const dispTime = t => {
var h = t.getUTCHours(), m = t.getUTCMinutes();
return (h ? h + 'h ' + twoDigits(m) : m) + 'm ' + twoDigits(t.getUTCSeconds() + 's')
};
function Countdown(minutes, seconds, callbackFn, successFn, scope) {
var self = this;
this.delay = 1000;
this.timer = setTimeout(function() { self.run(); }, this.delay);
this.callbackFn = callbackFn;
this.successFn = successFn;
this.endTime = new Date().getTime() + 1000 * (60 * minutes + seconds);
this.scope = scope || self;
}
Countdown.prototype.run = function() {
var self = this, timeRemaining = this.timeRemaining();
this.callbackFn.call(this.scope, timeRemaining);
if (timeRemaining < this.delay - 1) {
this.successFn.call(this.scope);
} else {
this.timer = setTimeout(function() { self.run(); }, this.delay);
}
};
Countdown.prototype.timeRemaining = function() {
return this.endTime - new Date().getTime();
};
(function($) {
$.fn.countdown = function(minutes, seconds, callbackFn, successFn) {
new Countdown(minutes, seconds, callbackFn, successFn, this);
return this;
};
})(jQuery);
$('#countdown').countdown(0, 10, function(msRemaining) {
this.html(dispTime(new Date(msRemaining)));
}, function() {
this.html("Ended");
$('.img-message').show();
});
.messaging,
.img-message {
display: none;
}
.img-container.opacity-overlay {
opacity: 0.6;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="countdown"></div>
<div class="messaging">
<p>messaging here</p>
</div>
<div class="img-container">
<div class="img-message">image message here</div>
</div>