Using jQuery.text() Causes Memory Leak - javascript

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;
}
});

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)

Javascript when live time strikes 23:00

I have be attempting this for quite a while now and cant get my head around it. I have a javascript which displays a live time. What i am trying to do is build an if statement that says if it hits 23:00:00 then open a link. can anyone help please? anything i use just blanks out the time :(
<script>
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('txt').innerHTML = h + ":" + m + ":" + s;
var t = setTimeout(startTime, 500);
}
function checkTime(i) {
if (i < 10) {i = "0" + i};
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="txt"></div>
You already calculate the time, just check to see if it's the time you want, and open a url.
function startTime() {
var today = new Date('Thu Jul 26 2018 23:00:00 GMT-0700 (Pacific Daylight Time)')
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
if (h === 23 && m === 0 && s === 0) {
window.open('https://www.stackoverflow.com', '_blank');
}
m = checkTime(m);
s = checkTime(s);
document.getElementById('txt').innerHTML = h + ":" + m + ":" + s;
var t = setTimeout(startTime, 500);
}
function checkTime(i) {
if (i < 10) {
i = "0" + i
};
return i;
}
<body onload="startTime()">
<div id="txt"></div>
</body>
A simple
...
document.getElementById('txt').innerHTML = h + ":" + m + ":" + s;
if (h == "23" && m == "00" && s == "00") {
alert("open link from here");
}
...
would do the trick.
Note:
You also have to check for s otherwise you'll open a new page every second.
refresh every second :
function timeLoop(){
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
var timeString = h+":"+m+":"+s
// print time
document.getElementById('txt').innerHTML = h + ":" + m + ":" + s;
// check timeString
if ( timeString === "23:00:00"){
// perform you actions here
}
}
document.body.onload = function(){
setInterval( timeLoop, 1000 );
}
What's happening here is
when body is loaded the timeLoop function starts looping every second, each loop updates the time displayed and checking it.
you can execute whatever code or function in side the if statement.
hope this helps
I think a simple setInterval() checking for the hour only would do it. The following code sets a interval checking the hour every 1 second. If the hour is 23 the interval is cleared to ensure that the triggered action runs only once and then does whatever you want to do. There is no need to check for minutes and seconds as well and this way you don't need to worry about leading zeros.
var interval = window.setInterval(function(){
var h = new Date().getHours();
if (h === 23) {
// clear interval to ensure that code runs only once
window.clearInterval(interval);
// do whatever you like
console.log(h);
}
},1000);

Javascript clock - server time

I need to show the server time on a clock. Below is the code i currently have. I get the server time with Ajax call. The problem is that if the user changes it's local/computer clock it will also update the script's clock which is not ok - it should continue without changing and i'm stuck. I've tried passing the serverTime within the setTimeout so it get's used every time as a reference but no luck with that.
var serverTime = 1490856278000;
var localTime = +Date.now();
var timeDiff = serverTime - localTime;
var realTime;
var date;
var hours;
var minutes;
var seconds;
setInterval(function () {
realTime = +Date.now() + timeDiff;
date = new Date(realTime);
hours = date.getHours();
minutes = date.getMinutes();
seconds = date.getSeconds();
document.getElementById('clock').innerHTML = hours + ':' + minutes + ':' + seconds;
}, 1000);
<div id="clock"></div>
You should be able to compare each realTime with the last one in your setInterval. If the difference is far from the 1000ms that it is supposed to be, do an ajax call to query the server time again and renew the timeDiff.
Also you can try to use performance.now instead of Date.now. The higher resolution is unnecessary and possibly expensive, but MDN states that
unlike Date.now(), the values returned by Performance.now() always increase at a constant rate, independent of the system clock (which might be adjusted manually or skewed by software like NTP)
Using How to create an accurate timer in javascript? and Bergi's answer I prepared an another way. I think you don't have to use the local time at all:
var serverTime = 1490856278000;
var expected = serverTime;
var date;
var hours;
var minutes;
var seconds;
var now = performance.now();
var then = now;
var dt = 0;
var nextInterval = interval = 1000; // ms
setTimeout(step, interval);
function step() {
then = now;
now = performance.now();
dt = now - then - nextInterval; // the drift
nextInterval = interval - dt;
serverTime += interval;
date = new Date(serverTime);
hours = date.getUTCHours();
minutes = date.getUTCMinutes();
seconds = date.getUTCSeconds();
document.getElementById('clock').innerHTML = hours + ':' + minutes + ':' + seconds;
console.log(nextInterval, dt); //Click away to another tab and check the logs after a while
now = performance.now();
setTimeout(step, Math.max(0, nextInterval)); // take into account drift
}
<div id="clock"></div>
The time will change because Date.now(); is getting it's time from the Client machine. There are no AJAX calls in your script.
More Updated with AM & PM
var serverTime = 1490856278000;
var expected = serverTime;
var date;
var h;
var m;
var s;
var now = performance.now();
var then = now;
var dt = 0;
var nextInterval = (interval = 1000);
setTimeout(step, interval);
function step() {
then = now;
now = performance.now();
dt = now - then - nextInterval;
nextInterval = interval - dt;
serverTime += interval;
date = new Date(serverTime);
h = date.getHours();
m = date.getMinutes();
s = date.getSeconds();
var session = "AM";
if (h == 0) {
h = 12;
}
if (h > 12) {
h = h - 12;
session = "PM";
}
h = h < 10 ? "0" + h : h;
m = m < 10 ? "0" + m : m;
s = s < 10 ? "0" + s : s;
var time = h + ":" + m + ":" + s + " " + session;
document.getElementById("NowTime").innerHTML = time;
now = performance.now();
setTimeout(step, Math.max(0, nextInterval));
}

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

addEventListener using a button doesn't do anything

Playing around with some Javascript and I'm trying to display the clock when a button is clicked. Using just the js without addEventListener works, it displays the clock in the target div. When I add addEventListener though, nothing happens. I'm quite new to programming and often overlook some typos and syntax errors but I've been through this many times and didn't find anything.
This is the js code:
document.addEventListener('DOMContentReady', function () {
document.getElementById('clock-button').addEventListener('click', startClock, false);
});
function startClock() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('clock').innerHTML = h + ":" + m + ":" + s;
t = setTimeout(function () {
startClock();
}, 500);
console.log("works");
}
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
And the jsfiddle here: http://jsfiddle.net/Em46R/1/
Replace DOMContentReady with DOMContentLoaded

Categories

Resources