javascript handle multiple instances of setTimeout()? - javascript

I have two buttons, show time, and stop time. when click on show time, it set up setTimeout() to update the current time. when stop time is clicked, i want to stop the time 5 sec later. the problem I'm having is that if I click on show time twice, then I click stop time, the time is till ticking. I need to click stop time twice in order to stop the time. so I think there are multiple instances of setTimeout() when i click show time multiple times. I'm wondering how can I make sure there is only one setTimeout(), so even show time is clicked multiple times, it only requires to click on stop time once to stop the time.
<body>
<script>
var iTimeout;
function startTime() {
var today = new Date();
var hour = today.getHours();
var min = today.getMinutes();
var sec = today.getSeconds();
document.getElementById('time').innerHTML =
hour + ":" + min + ":" + sec;
iTimeout = window.setTimeout(startTime, 1000);
}
function stopTimer() {
window.setTimeout(function() {
window.clearTimeout(iTimeout);
console.log("clear");
}, 5000);
}
</script>
</head>
<div id="time"></div>
<button onclick="stopTimer()">stop time</button>
<button onclick="startTime()">show time</button>
</body>

You can clear the iTimeout before starting the new timer in case the user clicks on start time twice
function startTime() {
var today = new Date();
var hour = today.getHours();
var min = today.getMinutes();
var sec = today.getSeconds();
document.getElementById('time').innerHTML =
hour + ":" + min + ":" + sec;
if(iTimeout)
{
window.clearTimeout(iTimeout);
}
iTimeout = window.setTimeout(startTime, 1000);
}

var iTimeout;
function startTime() {
var today = new Date();
var hour = today.getHours();
var min = today.getMinutes();
var sec = today.getSeconds();
document.getElementById('time').innerHTML =
hour + ":" + min + ":" + sec;
// clear the timeout if it exists.
if (iTimeout) {
window.clearTimeout(iTimeout);
}
iTimeout = window.setTimeout(startTime, 1000);
}
function stopTimer() {
window.setTimeout(function() {
window.clearTimeout(iTimeout);
console.log("clear");
}, 5000);
}
<div id="time"></div>
<button onclick="stopTimer()">stop time</button>
<button onclick="startTime()">show time</button>

As #Joyson and #Ayan said, you can check if the iTimeout is already set, and clear it upon every request to create a new timer. i'd do the same, although, if i have to call a function repeatedly after a specific delay, i'd use setInterval instead. makes the code clean.
<script>
var iTimeout;
function getTime() {
var today = new Date();
var hour = today.getHours();
var min = today.getMinutes();
var sec = today.getSeconds();
document.getElementById('time').innerHTML =
hour + ":" + min + ":" + sec;
}
function startTime(){
if(iTimeout)
window.clearInterval(iTimeout);
iTimeout = window.setInterval(getTime, 1000);
}
function stopTimer() {
window.setTimeout(function() {
window.clearInterval(iTimeout);
console.log("clear");
}, 5000);
}
</script>
<div id="time"></div>
<button onclick="stopTimer()">stop time</button>
<button onclick="startTime()">show time</button>
doesn't it?

Related

Time and date in JS

I'm creating simple web app that shows you what date and time is it now. It works good but i want to make it to be more dynamic so you can see time counting. What is best way to do this?
var hdate = document.getElementById('time');
var body = document.querySelector('body');
var bgM = document.getElementsByClassName('bgMorning')
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
hdate.textContent = dateTime;
you could write your code inside an interval like this to update it every second.
setInterval(function(){
//write you code here to be executed every second
}, 1000);
you'll need to re-render your display element too. Use something like this
<html>
<p id="displayElement"></p>
<script>
//use this code inside your setInterval function so it re-renders every second
document.getElementById("displayElement").innerHTML = `<p>${time}</p>`;
</script>
</html>
let me know how that works!
You just need to call setInterval(func, interval_milliseconds).
Also try using template literals (e.g. ${hours}:${minutes}) to construct your strings in a more readable style.
Use let as opposed to var unless you need to support old versions of I.E.
let timeEl = document.getElementById('time');
let updateTimeEl = () => {
let today = new Date();
let date = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`;
let time = `${today.getHours()}:${today.getMinutes()}:${today.getSeconds()}`;
timeEl.textContent = `${date} ${time}`;
};
setInterval(updateTimeEl, 1000);
<div id="time"></div>
Try this.
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
// add a zero in front of numbers<10
m = checkTime(m);
s = checkTime(s);
hdate.textContent = h + ":" + m + ":" + s;
// document.getElementById('time').innerHTML = h + ":" + m + ":" + s;
t = setTimeout(function() {
startTime()
}, 500);
}
startTime(); //it starts the timer
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
Not sure if your code is the best, but you can just wrap it in a setInterval.
setInterval(function(){
var hdate = document.getElementById('time');
var body = document.querySelector('body');
var bgM = document.getElementsByClassName('bgMorning')
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" +
today.getSeconds();
var dateTime = date+' '+time;
console.log(dateTime)
}, 1000)
The second argument in the setIterval function is the interval that the code runs in miliseconds. So this will print to the console every second (1000ms -> 1s)

Using jQuery.text() Causes Memory Leak

I am creating a single page application that will remain active and open for multiple days at a time in a browser. On this page I am displaying a timer in the top right corner. I have found however, that the way I am using the timer is leaking a small amount of memory.
https://jsfiddle.net/zbgonp84/
$(function(){
timer();
});
function timer(){
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
$("#timer").text(h + ":" + m + ":" + s);
var t = setTimeout(timer, 1000);
}
function checkTime(i) {
if (i < 10){
i = "0" + i;
}
return i;
}
I have recreated just the timer and the timer's div in a fiddle. If you open chrome's dev tools and record a time line, you can see that every second a new node is added to memory. If left for 24 hours, it will add a new node every second for the whole day and never gets collected.
I feel as if I am missing something fairly obvious as to why this is not being garbage collected, but what am I missing to unallocate the memory?
Create and substitute a reference to #timer element for calling jQuery() at each call to timer. Also, declare variable t outside of timer
$(function() {
const time = $("#timer");
var t;
timer();
function timer() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
time.text(h + ":" + m + ":" + s);
t = setTimeout(timer, 1000);
}
function checkTime(i) {
if (i < 10){
i = "0" + i;
}
return i;
}
});

JavaScript clock not showing current time on mobile devices

I got this JavaScript Code to display the current time on my website, works perfectly for desktop but it doesn't work on mobile devices
It freezes on the time when the user visits the page
Is it any way to make this possible? Something like refresh the script every sec to show the current time or any other solution?
document.getElementById("clock").innerHTML = GetTime();
function GetTime(){
var d = new Date();
var nhour = d.getHours(),nmin=d.getMinutes();
if (nmin<=9) {
nmin = "0" + nmin
}
return nhour+":"+nmin+"";
}
<span id="clock"></span>
Your help is really appreciated!
EDIT: Thanks to mdickin I realized the clock doesn't update even in desktop. So the entire code has something wrong.
Yes you could use a setInterval, which runs a function at regular intervals (in milliseconds).
function setTime()
{
document.getElementById("clock").innerHTML = GetTime();
}
setInterval(setTime,1000);
You could change the number of milliseconds to suit, depending on how accurate you want to be...but I doubt you would need to worry about being more than a second out either way.
Here's a link with more information about setInterval and setTimeout
Use setInterval to run your GetTime() function every second:
document.getElementById("clock").innerHTML = GetTime();
function GetTime(){
var d = new Date();
var nhour = d.getHours(),nmin=d.getMinutes();
if (nmin<=9) {
nmin = "0" + nmin
}
return nhour+":"+nmin+"";
}
setInterval(GetTime, 1000); // run GetTime every 1000ms
<span id="clock"></span>
Here is a simple program that I wrote in codepen to create a live JS timer. Basically all you need to do is call the function inside a setTimeout function and provide the frequency in milliseconds.
function startTimer() {
var today = new Date();
var hours = today.getHours();
var mins = today.getMinutes();
var sec = today.getSeconds();
mins = checkTime(mins);
sec = checkTime(sec);
document.getElementById('timer').innerHTML =
hours + ":" + mins + ":" + sec;
var t = setTimeout(startTimer, 100);
}
function checkTime(i) {
if (i < 10) {
i = "0" + i
};
return i;
}
<body onLoad="startTimer()">
<div id="timer"></div>
</body>
Here is the link to my codepen

Set exam time 30 minutes by Javascript error?

I am writing for web exam page ,in there I have to set 30 minutes to exam time.So I used onload and settimeout function to check if 30 minutes over,the question page is close and go to finish page.I want to add current minutes 30.But it's doesn't work,don't go to finish.php.!
<body onload="time()">
<!-- question code -->
<div id="time"></div><!-- show time -->
</body>
JS
<script>
function time(){
var j = new Date();
var hr = j.getHours();
var sec = j.getSeconds();
var min = j.getMinutes();
var m = min + 30;//set 30 minutes exam times
if (m === min) {
location.href = "finish.php";
}
document.getElementById('time').innerHTML = hr + ":" + min + ":" + sec;
setTimeout(function() {
time()
}, 1000);
}
</script>
Try with this
function time(){
setTimeout(function() {
location.href = "finish.php";
}, 30*60*1000);
setInterval(function() {
var j = new Date();
var hr = j.getHours();
var min = j.getMinutes();
var sec = j.getSeconds();
document.getElementById('time').innerHTML = hr + ":" + min + ":" + sec;
}, 1000);
}
function time() {
var time = 60 * 1; //Replace 1 with 30 minutes
var minutes, seconds;
setInterval(function () {
minutes = parseInt(time / 60)
seconds = parseInt(time % 60);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById('time').innerHTML = minutes + ":" + seconds;
time--;
if (time < 0) {
location.href = "finish.php";
}
}, 1000);
}
<body onload="time()">
<!-- question code -->
<div id="time"></div><!-- show time -->
</body>
Your are assigning new value to m every timeout. you should initialize, m only once.
also minute goes from 0-59 so you cant always check for it is equal to m + 30, thats wrong way of doing it
being said that its always better to do this timeout at server side, at client side there are enough ways to cheat around it

How to show current time in JavaScript in the format HH:MM:SS?

How do I show the current time in the format HH:MM:SS?
You can use native function Date.toLocaleTimeString():
var d = new Date();
var n = d.toLocaleTimeString();
This will display e.g.:
"11:33:01"
MDN: Date toLocaleTimeString
var d = new Date();
var n = d.toLocaleTimeString();
alert("The time is: \n"+n);
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
// add a zero in front of numbers<10
m = checkTime(m);
s = checkTime(s);
document.getElementById('time').innerHTML = h + ":" + m + ":" + s;
t = setTimeout(function() {
startTime()
}, 500);
}
startTime();
<div id="time"></div>
DEMO using javaScript only
Update
Updated Demo
(function () {
function checkTime(i) {
return (i < 10) ? "0" + i : i;
}
function startTime() {
var today = new Date(),
h = checkTime(today.getHours()),
m = checkTime(today.getMinutes()),
s = checkTime(today.getSeconds());
document.getElementById('time').innerHTML = h + ":" + m + ":" + s;
t = setTimeout(function () {
startTime()
}, 500);
}
startTime();
})();
You can do this in Javascript.
var time = new Date();
console.log(time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds());
At present it returns 15:5:18. Note that if any of the values are less than 10, they will display using only one digit, not two.
Check this in JSFiddle
Updates:
For prefixed 0's try
var time = new Date();
console.log(
("0" + time.getHours()).slice(-2) + ":" +
("0" + time.getMinutes()).slice(-2) + ":" +
("0" + time.getSeconds()).slice(-2));
You can use moment.js to do this.
var now = new moment();
console.log(now.format("HH:mm:ss"));
Outputs:
16:30:03
new Date().toTimeString().slice(0,8)
Note that toLocaleTimeString() might return something like 9:00:00 AM.
Use this way:
var d = new Date();
localtime = d.toLocaleTimeString('en-US', { hour12: false });
Result: 18:56:31
function realtime() {
let time = moment().format('h:mm:ss a');
document.getElementById('time').innerHTML = time;
setInterval(() => {
time = moment().format('h:mm:ss a');
document.getElementById('time').innerHTML = time;
}, 1000)
}
realtime();
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
<div id="time"></div>
A very simple way using moment.js and setInterval.
setInterval(() => {
moment().format('h:mm:ss a');
}, 1000)
Sample output
Using setInterval() set to 1000ms or 1 second, the output will refresh every 1 second.
3:25:50 pm
This is how I use this method on one of my side projects.
setInterval(() => {
this.time = this.shared.time;
}, 1000)
Maybe you're wondering if using setInterval() would cause some performance issues.
Is setInterval CPU intensive?
I don't think setInterval is inherently going to cause you significant performance problems. I suspect the reputation may come from an earlier era, when CPUs were less powerful. ... - lonesomeday
No, setInterval is not CPU intensive in and of itself. If you have a lot of intervals running on very short cycles (or a very complex operation running on a moderately long interval), then that can easily become CPU intensive, depending upon exactly what your intervals are doing and how frequently they are doing it. ... - aroth
But in general, using setInterval really like a lot on your site may slow down things. 20 simultaneously running intervals with more or less heavy work will affect the show. And then again.. you really can mess up any part I guess that is not a problem of setInterval. ... - jAndy
new Date().toLocaleTimeString('it-IT')
The it-IT locale happens to pad the hour if needed and omits PM or AM 01:33:01
Compact clock function:
setInterval(function() {
let d = new Date()
console.log(`${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`)
}, 1000);
This code will output current time in HH:MM:SS format in console, it takes into account GMT timezones.
var currentTime = Date.now()
var GMT = -(new Date()).getTimezoneOffset()/60;
var totalSeconds = Math.floor(currentTime/1000);
seconds = ('0' + totalSeconds % 60).slice(-2);
var totalMinutes = Math.floor(totalSeconds/60);
minutes = ('0' + totalMinutes % 60).slice(-2);
var totalHours = Math.floor(totalMinutes/60);
hours = ('0' + (totalHours+GMT) % 24).slice(-2);
var timeDisplay = hours + ":" + minutes + ":" + seconds;
console.log(timeDisplay);
//Output is: 11:16:55
This is an example of how to set time in a div(only_time) using javascript.
function date_time() {
var date = new Date();
var am_pm = "AM";
var hour = date.getHours();
if(hour>=12){
am_pm = "PM";
}
if (hour == 0) {
hour = 12;
}
if(hour>12){
hour = hour - 12;
}
if(hour<10){
hour = "0"+hour;
}
var minute = date.getMinutes();
if (minute<10){
minute = "0"+minute;
}
var sec = date.getSeconds();
if(sec<10){
sec = "0"+sec;
}
document.getElementById("time").innerHTML = hour+":"+minute+":"+sec+" "+am_pm;
}
setInterval(date_time,500);
<per>
<div class="date" id="time"></div>
</per>
new Date().toLocaleTimeString()
function realtime() {
let time = moment().format('hh:mm:ss.SS a').replace("m", "");
document.getElementById('time').innerHTML = time;
setInterval(() => {
time = moment().format('hh:mm:ss.SS A');
document.getElementById('time').innerHTML = time;
}, 0)
}
realtime();
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
<div id="time"></div>
Use
Date.toLocaleTimeString()
// Depending on timezone, your results will vary
const event = new Date('August 19, 1975 23:15:30 GMT+00:00');
console.log(event.toLocaleTimeString('en-US'));
// expected output: 1:15:30 AM
console.log(event.toLocaleTimeString('it-IT'));
// expected output: 01:15:30
console.log(event.toLocaleTimeString('ar-EG'));
// expected output: ١٢:١٥:٣٠
Source

Categories

Resources