Javascript app freezing after approximately two hours (memory leak?) - javascript

I'm currently developing a home automation user interface, running on a wall-mounted android (version 4.2.2) tablet, which, after a couple of minutes of inactivity, displays a "screensaver" html page.
As you can see in the screenshot above, this "screensaver" basically consists of the following features :
a clock displaying the current time and date, triggered by the script date_time.js and refreshed at one second interval;
a picture on the top right-hand side which shows the current status of the alarm;
a picture "Touchez l'écran pour quitter le mode veille" which is randomly repositioned every 3500 miliseconds.
Both points 2) and 3) above are run by another script stored in a script called "screensaver_run.js". The method getAlarmDataFromDatabase is retrieving data from my mysql database.
Now, for the problem statement: after approximately two hours, the whole screen freezes (both the clock and the repositioning script) in such a way that even the tablet is no longer pingable. I suspect that a memory leak is occurring but after a couple of sleepless nights ... and a lot of coffee ... I am not able to find out the root cause of my issue.
Reading some documentation on the internet, notably https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript, I have already implemented some changes such as changing the declaration of the variables from "var" to "let".
In Chrome, I run the script during 2 1/2 minutes and profiled the memory usage (I have the heaptimeline file available, if it can be of any help, but here I'm not quite sure how to analyse it?):
Besides, I queried the console for :
performance.memory.usedJSHeapSize and got some changing values :
3430886, 3195206, 4743246, 3402767, etc
performance.memory.jsHeapSizeLimit and got : 4294705152
Does anyone have any hint where to start investigating, knowing that debugging possibilities of this tablet are not as advanced as on a modern browser? My tablet is "already" 5 years old... Upgrading this tablet is not an option.
Many thanks for your time reading me and I do hope that my post is understandable, well documented and in the future, could help other to have restful nights :)
The code of my html page (named after 'screen_saver.html) is the following :
<!DOCTYPE html>
<html>
<head>
<title>Domoos | Screen saver screen</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta http-equiv="pragma" content="no-cache">
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="css/mystyle_saver.css?rnd=999" />
<script type="text/javascript" src="scripts/date_time.js"></script>
<script type="text/javascript" src="scripts/screensaver_run.js"></script>
</head>
<body onload="runScreenSaver(); setup();">
<div style="position:absolute" id="randomPlacement">
<p><img src="assets/pictures/texte_sortie_veille.png" alt ="" style="width:90px;height:90px;" border="0"></p>
</div>
<div id="svg">
<svg height="210" width="1020">
<line x1="11" y1="100" x2="1015" y2="100" style="stroke:rgb(69,69,66);stroke-width:3" />
</svg>
</div>
<div id="date"></div>
<div id="time"></div>
<div id="icon_alarm">
<img id="img_alarm" src="assets/icons/alarme_eteinte.png" alt ="" style="width:27px;height:35px;">
</div>
<div id="tag_temperature">
<p>21°C</p>
</div>
<div id="tag_free_text">
<p>151<sup>ème</sup> jour de l'année 2020.<br>Bonsoir</p>
</div>
<div id="meteo_icon">
<img src="assets/meteo_icons/eclaircies-big.png" alt="" style="width:40px;height:40px;">
</div>
<div id="tag_weather_condition">
<p>Eclaircies</p>
</div>
</body>
</html>
Code of my javasript file screensaver_run.js:
function runScreenSaver()
{
let xmin = 0;
let xmax = 890;
let ymin = 0;
let ymax = 430;
let sDate;
let sTime;
let bOverlapAuthorised;
let bDisplayPos;
let zRandomImage;
let xCoord;
let yCoord;
let xCoordStr;
let yCoordStr;
bOverlapAuthorised = true;
bDisplayPos = false;
// If overlap is forbidden, the x min and y min parameters will be redefined to be slightly below the line
if (!bOverlapAuthorised)
{
xmin = 15;
ymin = 130;
}
// Computes a random x and y, based on the min and ma
xCoord = Math.floor((Math.random()*xmax)+xmin);
yCoord = Math.floor((Math.random()*ymax)+ymin);
xCoordStr = xCoord.toString() + "px";
yCoordStr = yCoord.toString() + "px";
zRandomImage = document.getElementById("randomPlacement");
zRandomImage.style.left = xCoordStr;
zRandomImage.style.top = yCoordStr;
// Instead of displaying a message in the 'tag_free_text',
// shows the randomly defined coordinates of the 'randomPlacement' object
if (bDisplayPos)
{
document.getElementById("tag_free_text").innerHTML = 'X:' + xCoordStr + '<br>Y:' + yCoordStr;
}
document.getElementById("date").innerhtml=getTimeDate('date');
getAlarmDataFromDatabase();
zRandomImage = null;
xCoord = null;
yCoord = null;
xCoordStr = null;
yCoordStr = null;
setTimeout('runScreenSaver()','3500');
}
function setup()
{
this.addEventListener("mousemove", exitScreenSaver, false);
this.addEventListener("mousedown", exitScreenSaver, false);
this.addEventListener("keypress", exitScreenSaver, false);
this.addEventListener("DOMMouseScroll", exitScreenSaver, false);
this.addEventListener("mousewheel", exitScreenSaver, false);
this.addEventListener("touchstart", exitScreenSaver, false);
this.addEventListener("MSPointerMove", exitScreenSaver, false);
}
function getAlarmDataFromDatabase()
{
let ajax = new XMLHttpRequest();
let id_component;
let technical_name_html;
let comp_value;
let data;
ajax.open("GET", "php/data4screensaver1.php", true);
ajax.send();
ajax.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
data = JSON.parse(this.responseText);
for(var a = 0; a < data.length; a++)
{
id_component = data[a]['id_component'];
technical_name_html = data[a]['technical_name_html'];
comp_value = parseInt(data[a]['value']);
}
data = null;
console.log("ID Component: " + id_component);
//console.log("Valeur de l'alarme : " + comp_value);
switch (comp_value)
{
case 0:
case 50:
case 100:
displayPictureAlarm(comp_value);
break;
default:
displayPictureAlarm(-1);
break;
}
}
};
ajax = null;
id_component = null;
technical_name_html = null;
comp_value = null;
}
function exitScreenSaver(e)
{
goActive(e);
}
function goActive(event)
{
// do something
console.log(".. active ..");
//event.preventDefault();
this.removeEventListener("mousemove", exitScreenSaver);
this.removeEventListener("mousedown", exitScreenSaver);
this.removeEventListener("keypress", exitScreenSaver);
this.removeEventListener("DOMMouseScroll", exitScreenSaver);
this.removeEventListener("mousewheel", exitScreenSaver);
this.removeEventListener("touchstart", exitScreenSaver);
this.removeEventListener("MSPointerMove", exitScreenSaver);
window.open("index.html","_self");
}
function displayPictureAlarm(pValue)
{
let z;
z = document.getElementById("img_alarm");
if (pValue == 0) // désarmée
{
z.src = "assets/icons/alarme_desarmee.png";
}
if (pValue == 50) // partielle
{
z.src = "assets/icons/alarme_partielle.png";
}
if (pValue == 100) // totale
{
z.src = "assets/icons/alarme_totale.png";
}
if (pValue == -1) // éteinte
{
z.src = "assets/icons/alarme_eteinte.png";
}
z = null;
}
Code of my javascript file datetime.js (as called in the the method runScreenSaver above):
function getDate(id)
{
date = new Date;
year = date.getFullYear();
month = date.getMonth();
month += 1;
d = date.getDate();
day = date.getDay();
days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
if (d<10)
{
d = "0"+d;
}
if(month<10)
{
month = "0"+month;
}
result = ''+days[day]+' '+d+'.'+month+'.'+year;
result = days[day]+' '+d+'.'+month+'.'+year;
document.getElementById(id).innerHTML = result;
setTimeout('getDate("'+id+'");','1000');
return true;
}
function getTimeDateMainScreen()
{
var za;
var zb;
var zc;
var mydate;
var result1;
var result2;
var result3;
mydate = new Date;
year = mydate.getFullYear();
month = mydate.getMonth();
day = mydate.getDate();
weekday = mydate.getDay();
hrs = mydate.getHours();
mns = mydate.getMinutes();
secs = mydate.getSeconds();
days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
month += 1;
if (day < 10)
{
day = "0" + day;
}
if(month < 10)
{
month = "0" + month;
}
if(hrs < 10)
{
hrs = "0" + hrs;
}
if(mns < 10)
{
mns = "0" + mns;
}
if(secs < 10)
{
secs = "0" + secs;
}
//result = ''+days[weekday]+' '+d+'.'+month+'.'+year;
//result = days[weekday]+' '+d+'.'+month+'.'+year;
result1 = day + "." + month + "." + year;
result2 = days[weekday];
result3 = hrs + ":" + mns + ":" + secs;
za = document.getElementById("curr_date");
zb = document.getElementById("curr_weekday");
zc = document.getElementById("curr_time");
za.innerHTML = result1;
zb.innerHTML = result2;
zc.innerHTML = result3;
za = null;
zb = null;
zc = null;
mydate = null;
result1 = null;
result2 = null;
result3 = null;
setTimeout('getTimeDateMainScreen();','500');
}
function getTime(id)
{
date = new Date;
h = date.getHours();
if(h<10)
{
h = "0"+h;
}
m = date.getMinutes();
if(m<10)
{
m = "0"+m;
}
s = date.getSeconds();
if(s<10)
{
s = "0"+s;
}
result = ''+h+':'+m+':'+s;
document.getElementById(id).innerHTML = result;
setTimeout('getTime("'+id+'");','1000');
return true;
}
function getTime2()
{
date = new Date;
h = date.getHours();
if(h<10)
{
h = "0"+h;
}
m = date.getMinutes();
if(m<10)
{
m = "0"+m;
}
s = date.getSeconds();
if(s<10)
{
s = "0"+s;
}
result = ''+h+':'+m+':'+s;
document.getElementById("time").innerHTML = result;
setTimeout('getTime2();','1000');
}
function getTimeDate(id)
{
let date;
let year;
let month;
let d;
let day;
let days;
let h;
let m;
let s;
let result;
date = new Date;
console.log("J'affiche la date3");
year = date.getFullYear();
month = date.getMonth();
month += 1;
d = date.getDate();
day = date.getDay();
days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
h = date.getHours();
m = date.getMinutes();
s = date.getSeconds();
if (d<10)
{
d = "0"+d;
}
if(month<10)
{
month = "0"+month;
}
if(h<10)
{
h = "0"+h;
}
if(m<10)
{
m = "0"+m;
}
if(s<10)
{
s = "0"+s;
}
result = ''+days[day]+' '+d+'.'+month+'.'+year +' ' + h+':'+m+':'+s;
document.getElementById(id).innerHTML = result;
date = null;
year = null;
month = null;
d = null;
day = null;
days = null;
h = null;
m = null;
s = null;
result = null;
setTimeout('getTimeDate("'+id+'");','1000');
return true;
}
And, finally, here is my php (data4screensaver1.php) to retrieve the data from my mysql database :
<?php
$host = "ip_Address_db";
$db_user_encoded = "user_encoded";
$db_password_encoded = "pw_encoded";
$db_name_encoded = "db_name_encoded";
$conn = mysqli_connect($host, (encrypt_decrypt('decrypt', $db_user_encoded)), (encrypt_decrypt('decrypt', $db_password_encoded)), (encrypt_decrypt('decrypt', $db_name_encoded )));
$result = mysqli_query($conn, "CALL sp_tbl_domotique_components_get_lab61()");
$data = array();
while ($row = mysqli_fetch_object($result))
{
array_push($data, $row);
}
echo json_encode($data);
exit();
function encrypt_decrypt($action, $string)
{
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = '$SecretKey$';
$secret_iv = '$SecretIV$';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if ( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if( $action == 'decrypt' ) {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
?>

Related

12 hour clock not displaying, but 24 hour clock displaying fine

I have this code so that when I click the buttons, it switches between the 12 hours clock and 24 hours clock.
The 24 hour clock displayed, but when I click the 12 hour clock button, nothing happens.
Google Inspect also says nothing. Any help would be appreciated.
function twelvehour() {
var dat = new Date();
var h = dat.getHours()
if (h >= 13) {
var h = dat.getHours() - 12
} else {
var h = dat.getHours()
}
var m = dat.getMinutes()
var s = dat.getSeconds()
if (h >= 12) {
document.getElementById("clock").innerHTML = h + ":" + m + ":" + s + "pm"
} else {
document.getElementById("clock").innerHTML = h + ":" + m + ":" + s
}
}
function tfourhour() {
var dat1 = new Date();
var h1 = dat1.getHours()
var m1 = dat1.getMinutes()
var s1 = dat1.getSeconds()
document.getElementById("clock").innerHTML = h1 + ":" + m1 + ":" + s1
}
setInterval(twelvehour, 1000);
setInterval(tfourhour, 1000);
document.getElementById("twelve").onclick = twelvehour()
document.getElementById("tfour").onclick = tfourhour()
<html>
<head>
<style>
button {
display: inline-block;
}
</style>
<title>Assignment 9c Clock</title>
</head>
<body>
<button type="button" style="width=500, height=500" id="twelve">12 Hour Clock</button>
<button type="button" style="width=500, height=500" id="tfour">24 Hour Clock</button>
<br>
<p id="clock"></p>
<script type="text/javascript" src="sample4.js">
</script>
</body>
</html>
You run two functions at the same time by calling setIterval twice.
twelvehour function doesn't work properly since you set h before it displayed.
Event handlers should be mapped with a function itself not a result of it.
And consider using a function that store the selected function.
let f = twelvehour;
f();
function twelvehour() {
var dat = new Date();
dat.setHours(14); // for test
var h = dat.getHours()
var m = dat.getMinutes()
var s = dat.getSeconds()
if (h >= 12) {
document.getElementById("clock").innerHTML = (h - 12) + ":" + m + ":" + s + "pm"
} else {
document.getElementById("clock").innerHTML = h + ":" + m + ":" + s
}
}
function tfourhour() {
var dat1 = new Date();
dat1.setHours(14); // for test
var h1 = dat1.getHours()
var m1 = dat1.getMinutes()
var s1 = dat1.getSeconds()
document.getElementById("clock").innerHTML = h1 + ":" + m1 + ":" + s1
}
setInterval(() => f(), 1000);
document.getElementById("twelve").onclick = () => { f = twelvehour; f(); }
document.getElementById("tfour").onclick = () => { f = tfourhour; f(); }
<html>
<head>
<style>
button {
display: inline-block;
}
</style>
<title>Assignment 9c Clock</title>
</head>
<body>
<button type="button" style="width=500, height=500" id="twelve">12 Hour Clock</button>
<button type="button" style="width=500, height=500" id="tfour">24 Hour Clock</button>
<br>
<p id="clock"></p>
</script>
</body>
</html>
Your main issue here is assigning onclick in a wrong way. You should drop the parentheses:
document.getElementById("twelve").onclick = twelvehour
Or, put it in the HTML:
<button type="button"
style="width: 500px; height: 500px;"
id="twelve"
onclick="twelvehour()">12 Hour Clock</button>
Here's how I would do it:
function Clock(displayFunc, twelveHour = true, interval = 1000){
let clock;
this.twelveHour = twelveHour; this.interval = interval;
this.start = ()=>{
const fun = ()=>{
let d = new Date, h = d.getHours(), m = d.getMinutes(), s = d.getSeconds(), z = d.getMilliseconds(), p = false;
if(this.twelveHour){
if(h > 12){
h -= 12; p = 'pm';
}
else{
p = 'am';
}
}
else if(h < 10){
h = '0'+h;
}
if(m < 10)m = '0'+m;
if(s < 10)s = '0'+s;
if(z < 10){
z = '00'+z;
}
else if(z < 99){
z = '0'+z;
}
displayFunc({hours:h.toString(), minutes:m.toString(), seconds:s.toString(), am_pm:p});
}
fun(); clock = setInterval(fun, this.interval);
return this;
}
this.stop = ()=>{
clearInterval(clock); clock = undefined;
return this;
}
}
let doc, bod, I; // for use on other loads
addEventListener('load', ()=>{
doc = document; bod = doc.body; I = id=>doc.getElementById(id);
const digital = I('digital'), clock = new Clock(o=>{
digital.textContent = o.hours+':'+o.minutes+':'+o.seconds+' '+o.am_pm;
});
clock.start();
}); // end load
<div id='digital'></div>

Ajax Request Not Always Consistent

I have been developing a site that will provide schedules created by people. I'm using Alienware to develop it and the ajax code works perfectly on the laptop all of the time. I am using IE. However, if I access my site on my Samsung Smart TV or my HTC U11 phone, Ajax isn't consistent. It displays the data I am requesting, however, when I sum up a total of hours for the week, it sometimes displays the correct hours, or sometimes shows 0 hours, when the user is scheduled for the week. Why is it inconsistent between devices? I know that Ajax is recommended for IE. As I said, though, it sometimes will display the correct total weekly hours, and other times it will just show zero. This issue isn't occurring on my Alienware.
I've already tried using onload instead of onreadystatechange. I've set the request to asynchronous and synchronous. Whether it's set to true or false, on my other devices, it fails to be consistent. I've tried it as a post and get method, and both also are inconsistent. What is wrong with my code?
function getThisWeek(str5) {
lastDate = new Date(str5);
// getting dates for this week to be displayed...
this.math = dayInput.length - 1;
this.math0 = 0 - new Date(str5).getDay();
// getting week total hour length, to determine how many times this code executes...
weekSum = 0;
totals = [];
for (this.i = 0; this.i < weekTotalHours.length; this.i++) {
str3 = this.i;
this.date = new Date(str5);
for (this.ii = (this.i * (7)) - new Date().getDay(); this.ii < (7 * (this.i + 1)) - new Date().getDay(); this.ii++) {
totalHours = 0;
this.date = new Date(str5);
this.date = new Date(this.date.setDate(this.date.getDate() + (this.ii)));
// which element position the total daily hours belongs to when displaying them...
this.pos = this.ii + new Date().getDay();
thisDayChart[this.pos].innerHTML = "";
// displaying the date
dayInput[this.pos].innerHTML = this.date.getDate();
// highlighting today's date...
if (this.date.getDate() == new Date(str5).getDate() && this.date.getMonth() == new Date().getMonth()) {
dayInput[this.pos].style.color = "white";
dayInput[this.pos].style.backgroundColor = "silver";
dayInput[this.pos].style.borderRadius = "0px";
thisDay[this.pos].style.border = "2px double lightblue";
} else {
dayInput[this.pos].style.color = "";
dayInput[this.pos].style.backgroundColor = "";
dayInput[this.pos].style.borderRadius = "";
thisDay[this.pos].style.border = "";
}
// getting schedule from database...
this.xmlhttp = new XMLHttpRequest();
this.xmlhttp.pos = this.pos;
this.xmlhttp.ipos = this.i;
this.xmlhttp.d = months[this.date.getMonth()] + " " + this.date.getDate() + ", " + this.date.getFullYear();
this.xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//alert(this.responseText);
dayInput[this.pos].m = months[new Date(this.d).getMonth()];
dayInput[this.pos].weekDay = days[new Date(this.d).getDay()];
// how many weeks in the year is user...
this.islpyr = new Date(this.d);
this.islpyr = this.islpyr.setMonth(1);
this.islpyr = new Date(new Date(this.islpyr).setDate(29));
if (this.islpyr.getMonth() == 2) {
mlens[1] = 28;
} else {
mlens[1] = 29;
}
// getting total amount of days for the year...
this.yrlen = 0;
for (this.iii = 0; this.iii < mlens.length; this.iii++) {
this.yrlen += mlens[this.iii];
}
// getting total weeks
this.wklen = this.yrlen / 7;
this.wklen = Math.round(this.wklen);
this.week = 0;
for (this.iii = 0; this.iii < new Date(this.d).getMonth(); this.iii++) {
this.week += mlens[this.iii];
}
this.week += new Date(this.d).getDate();
this.week /= 7;
this.week = Math.round(this.week) + 1;
// rounding and displaying current week number...
if (new Date(this.d).getDay() == 0) {
myDayWrapper[this.ipos].weekLabel = "Week " + this.week + " of " + this.wklen;
}
if (this.pos == 0) {
weekDisplay[0].innerHTML = myDayWrapper[0].weekLabel;
}
// which day of the year it is... how many days in the year is the user...
this.yrpos = 0;
for (this.iv = 0; this.iv < new Date(this.d).getMonth(); this.iv++) {
this.yrpos += mlens[this.iv];
}
this.yrpos += new Date(this.d).getDate();
thisDayTitle[this.pos].innerHTML = "Day " + this.yrpos + " of " + this.yrlen;
totalHours = 0;
this.schedule = "" + this.responseText;
// if user is unscheduled, do this first... 'undefined' literally means there isn't a schedule for that specific day.
if (this.schedule.search("Undefined") >= 0) {
this.elem = document.createElement("div");
this.elem.setAttribute("class","not_scheduled");
this.elem.innerHTML = "Unscheduled";
thisDayChart[this.pos].appendChild(this.elem);
this.elem = document.createElement("div");
this.elem.setAttribute("class","pick_up_shift_btn");
this.elem.innerHTML = "Claim Shifts";
this.elem.i = this.pos;
this.elem.ipos = this.ipos;
this.elem.onclick = function() {
popUpWrap[1].style.display = "block";
this.datesd = [];
for (this.i = this.ipos * 7; this.i < 7 * (this.ipos + 1); this.i++) {
this.datesd.push(dayInput[this.i].innerHTML);
}
for (this.i = 0; this.i < 7; this.i++) {
shiftClaimDate[this.i].innerHTML = this.datesd[this.i];
popUpShiftDay[this.i].innerHTML = dayInput[this.i].weekDay;
this.strrr = "" + dayInput[this.i].m;
this.strrr = this.strrr.substring(0,3);
shiftClaimMonth[this.i].innerHTML = this.strrr;
}
}
thisDayChart[this.pos].appendChild(this.elem);
if (totals.length - 1 == this.pos) {
} else {
totals.push(0);
}
} else {
// getting daily total...
this.schedule = this.schedule.split(",");
for (this.iii = 0; this.iii < this.schedule.length; this.iii++) {
this.str = "" + this.schedule[this.iii];
this.str = this.str.split("=");
this.dateString = "December 22, 1991";
switch (this.str[0]) {
case "shift_start":
this.start = new Date(this.dateString + " " + this.str[1]);
this.end = this.schedule[this.schedule.length - 1] + "";
this.end = this.end.split("=");
this.end = new Date(this.dateString + " " + this.end[1]);
this.hours = (this.end.getHours() - this.start.getHours()) * 60;
this.hours = this.hours - (this.start.getMinutes() + this.end.getMinutes());
this.hours /= 60;
totalHours += this.hours;
weekSum += totalHours;
break;
case "break_start":
this.start = new Date(this.dateString + " " + this.str[1]);
this.end = this.schedule[this.iii + 1] + "";
this.end = this.end.split("=");
this.end = new Date(this.dateString + " " + this.end[1]);
this.hours = (this.end.getHours() - this.start.getHours()) * 60;
this.hours = this.hours - (this.start.getMinutes() + this.end.getMinutes());
this.hours /= 60;
weekSum -= this.hours;
totalHours -= this.hours;
this.s = "s";
if (totalHours == 1) {
this.s = "";
}
thisDayChart[this.pos].innerHTML = totalHours + " hour" + this.s;
break;
}
}
}
weekTotalHours[this.ipos].innerHTML = "Week Total: " + weekSum;
//alert(weekSum);
// displaying hour totals...
if (new Date(this.d).getDay() == 6) {
weekSum = 0;
}
totalHours = 0;
}
}
this.xmlhttp.open("GET","/js/data/schedule.html?date="+ months[this.date.getMonth()] + " " + this.date.getDate() + ", " + this.date.getFullYear(),false);
this.xmlhttp.send();
}
}
}
I expect every device to be consistent with the hour total it should be displaying, on every device that Ajax should work on.

I want countdown timer to redirect to url after timer hits 0

I have a working countdown timer but want it to redirect to an url or show a popup with a message to continue to another url when the counter hits zero. any advice is appreciated.
countdown.js
function calcage(secs, num1, num2) {
s = ((Math.floor(secs/num1))%num2).toString();
if (LeadingZero && s.length < 2)
s = "0" + s;
return "<b>" + s + "</b>";
}
function CountBack(secs) {
if (secs < 0) {
document.getElementById("cntdwn").innerHTML = FinishMessage;
return;
}
DisplayStr = DisplayFormat.replace(/%%D%%/g, calcage(secs,86400,100000));
DisplayStr = DisplayStr.replace(/%%H%%/g, calcage(secs,3600,24));
DisplayStr = DisplayStr.replace(/%%M%%/g, calcage(secs,60,60));
DisplayStr = DisplayStr.replace(/%%S%%/g, calcage(secs,1,60));
document.getElementById("cntdwn").innerHTML = DisplayStr;
if (CountActive)
setTimeout("CountBack(" + (secs+CountStepper) + ")", SetTimeOutPeriod);
}
function putspan(backcolor, forecolor) {
document.write("<span id='cntdwn'></span>");
}
if (typeof(BackColor)=="undefined")
BackColor = "white";
if (typeof(ForeColor)=="undefined")
ForeColor= "black";
if (typeof(TargetDate)=="undefined")
TargetDate = 17;/* number of hours "12/31/2020 5:00 AM";*/
if (typeof(DisplayFormat)=="undefined")
DisplayFormat = "%%D%% Days, %%H%% Hours, %%M%% Minutes, %%S%% Seconds.";
if (typeof(CountActive)=="undefined")
CountActive = true;
if (typeof(FinishMessage)=="undefined")
FinishMessage = "";
if (typeof(CountStepper)!="number")
CountStepper = -1;
if (typeof(LeadingZero)=="undefined")
LeadingZero = true;
CountStepper = Math.ceil(CountStepper);
if (CountStepper == 0)
CountActive = false;
var SetTimeOutPeriod = (Math.abs(CountStepper)-1)*1000 + 990;
putspan(BackColor, ForeColor);
//var dthen = new Date(TargetDate);
//var dnow = new Date();
//if(CountStepper>0)
// ddiff = new Date(dnow-dthen);
//else
ddiff = new Date(TargetDate * 300000);
gsecs = Math.floor(ddiff.valueOf()/1000);
CountBack(gsecs);
html
<!-- COUNTDOWN TIMER -->
<div style="text-align:center">
<div class="content">
<div class="box">
<div id="top">
<h2 style="line-height: 20px">You have <span style="color:red; font-size:20px">
<script language="JavaScript">
TargetDate = 1;
//BackColor = "palegreen";
//ForeColor = "navy";
CountActive = true;
LeadingZero = true;
DisplayFormat = "%%H%%:%%M%%:%%S%%";
</script><script type="text/javascript" src="js/countdown.js"></script></span> to claim your FREE spins.</h2>
</p>
</div>
</div>
The popup should be simple with just a statement and an option to continue.
You already check wether the countdown is complete here:
if (secs < 0) {
document.getElementById("cntdwn").innerHTML = FinishMessage;
return;
}
So you could simply add the changes into there, or call out to a "countdownComplete" type function. e.g.
if (secs < 0) {
document.getElementById("cntdwn").innerHTML = FinishMessage;
countdownComplete();
return;
}
With a countdownComplete function available somewhere relevant in the script, containing something like:
function countdownComplete(){
document.location.href = "http://www.google.com";
}

javascript count down to show days?

I have this javascript countdown that will show seconds. I need to know how I can show days in the counter instead of second.
i.e. 1 day, 2 hours left.
this is the code:
<script type="text/javascript">
var MAX_COUNTER = 1000;
var counter = null;
var counter_interval = null;
function setCookie(name,value,days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires="+date.toGMTString();
}
else {
expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function deleteCookie(name) {
setCookie(name,"",-1);
}
function resetCounter() {
counter = MAX_COUNTER;
}
function stopCounter() {
window.clearInterval(counter_interval);
deleteCookie('counter');
}
function updateCounter() {
var msg = '';
if (counter > 0) {
counter -= 1;
msg = counter;
setCookie('counter', counter, 1);
}
else {
counter = MAX_COUNTER;
}
var el = document.getElementById('counter');
if (el) {
el.innerHTML = msg;
}
}
function startCounter() {
stopCounter();
counter_interval = window.setInterval(updateCounter, 1000);
}
function init() {
counter = getCookie('counter');
if (!counter) {
resetCounter();
}
startCounter();
}
init();
</script>
at the moment it only shows seconds and it will restart itself once it hits 0.
http://jsfiddle.net/h2DEr/1/
function updateCounter() {
var msg = '';
if (counter > 0) {
counter -= 1;
msg = convertSecondsToDays(counter);
setCookie('counter', counter, 1);
}
else {
counter = MAX_COUNTER;
}
var el = document.getElementById('counter');
if (el) {
el.innerHTML = msg;
}
}
Here is the function that converts seconds to days
function convertSecondsToDays(sec) {
var days, hours,rem,mins,secs;
days = parseInt(sec/(24*3600));
rem = sec - days*3600
hours = parseInt(rem/3600);
rem = rem - hours*3600;
mins = parseInt(rem/60);
secs = rem - mins*60;
return days +" days " + hours +" hours "+mins + " mins "+ secs + " seconds";
}
update: after #sanya_zol's answer and comments from David Smith
since setInterval is not supposed to run every second, you need to change your strategy a little bit. I have modified the fiddle for that as well
Set MAX_COUNTER to a value when you want it to expire.
instead of decreasing the counter by -1, check the current time, subtract it from the expiry date and display it.
EXPIRY_SECONDS = 24*60*60;
MAX_COUNTER = parseInt(new Date().getTime()/(1000)) + EXPIRY_SECONDS;
function updateCounter() {
var msg = '',curTime = parseInt(new Date().getTime()/1000);
if (curTime < MAX_COUNTER) {
msg = convertSecondsToDays(MAX_COUNTER- curTime);
setCookie('counter', MAX_COUNTER- curTime, 1);
}
else {
MAX_COUNTER = parseInt(new Date().getTime()/1000) + EXPIRY_SECONDS;
}
var el = document.getElementById('counter');
if (el) {
el.innerHTML = msg
}
}
counter_interval = window.setInterval(updateCounter, 1000);
The 1000 is value in milliseconds so how many milliseconds are there in a day?
counter_interval = window.setInterval(updateCounter, 1000*60*60*24);
addition to vdua's answer:
Your code is really badly written.
It uses setInterval which counter is not precise (moreover, it have very, very bad precision) - so your counter's second will be equal to 1.05-1.2 real seconds (difference between real time and counter will accumulate).
You should check system time (via (new Date).getTime() ) every time at lower intervals (like 100 ms) to get precise counter.

Forcing page refresh at a specific time with timezone

I'm trying to force a page to refresh with js at a specific time, after digging around I found the script below. However, it doesn't appear to take into consideration timezones. How would I implement that?
<html>
<head>
<title></title>
<script type="text/javascript">
function refreshAt(hours, minutes, seconds) {
var now = new Date();
var then = new Date();
if(now.getHours() > hours ||
(now.getHours() == hours && now.getMinutes() > minutes) ||
now.getHours() == hours && now.getMinutes() == minutes && now.getSeconds() >= seconds) {
then.setDate(now.getDate() + 1);
}
then.setHours(hours);
then.setMinutes(minutes);
then.setSeconds(seconds);
var timeout = (then.getTime() - now.getTime());
setTimeout(function() { window.location.reload(true); }, timeout);
}
refreshAt(15,06,0); //Will refresh the page at 3:06pm
</script>
</head>
<body onLoad="setInterval('getCurrentTime()', 1000);">
<div id="time"></div>
content
</body>
</html>
Here you go, reload will occur for every user exactly as you define in global vars in script:
EDIT!!! I had bug in code so I have updated the script...
EDIT working example:
http://simplestudio.rs/yard/tinediffredir/content.html
<html>
<head>
<title>Chk diff and reload if match</title>
<script>
var reload_time = "15060"; // this is 15:06:00 - change to desired reload time
var reload_hour_diff = 15; // for cheking diff - change to desired hours
var reload_minute_diff = 6; // for cheking diff - change to desired minutes
var time_zone_offset = "-5"; // globally looking from GMT time, change this according to DST
var reload_time_checker = setInterval(function(){reload_page()},300);
var diff = null;
function chk_reload_moment(offset) {
dat = new Date();
utc = dat.getTime() + (dat.getTimezoneOffset() * 60000);
default_date = new Date(utc + (3600000*offset));
var default_year = default_date.getFullYear();
var default_month = default_date.getMonth();
var default_day = default_date.getDate();
var default_hour = default_date.getHours();
var default_minutes = default_date.getMinutes();
var default_seconds = default_date.getSeconds();
user_date = new Date();
var user_year = user_date.getFullYear();
var user_month = user_date.getMonth();
var user_day = user_date.getDate();
var user_hour = user_date.getHours();
var user_minutes = user_date.getMinutes();
var user_seconds = user_date.getSeconds();
user_current = user_hour+""+user_minutes+""+user_seconds;
default_current_f = default_day+"/"+default_month+"/"+default_year+" "+default_hour+":"+default_minutes+":"+default_seconds;
user_current_f = user_day+"/"+user_month+"/"+user_year+" "+user_hour+":"+user_minutes+":"+user_seconds;
var timeEnd = new Date(user_current_f);
var timeEndH = timeEnd.getHours();
var timeEndM = timeEnd.getMinutes();
var new_reload_minute_diff = 60+reload_minute_diff;
diff = (timeEndH - reload_hour_diff + 12) + " hours " + (new_reload_minute_diff - timeEndM) + " minutes";
if (user_current == reload_time) {
return true;
}
else {
return false;
}
}
function reload_page() {
var chktime = chk_reload_moment(time_zone_offset);
if (chktime) {
window.location.reload();
}
else {
var timer_div = document.getElementById('timer');
timer_div.innerHTML = "remaining: " + diff + " until new content";
}
}
</script>
</head>
<body>
<div id="timer">
</div>
</body>
</html>
I think it is clear how to configure it but if you have some problems feel free to ask...

Categories