JavaScript timer is resetting while refreshing the page - timer

I got a count down timer script.. I'm going to use it for a online examination.. But now the problem is it is resetting while refreshing the page...
Any idea to prevent the resetting the time and continue without any problem if they refresh the page too?
here is the code
<script>
var mins;
var secs;
function cd() {
mins = 1 * m("2"); // change minutes here
secs = 0 + s(":01"); // change seconds here (always add an additional second to your total)
redo();
}
function m(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(0, i));
}
function s(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(i + 1, obj.length));
}
function dis(mins,secs) {
var disp;
if(mins <= 9) {
disp = " 0";
} else {
disp = " ";
}
disp += mins + ":";
if(secs <= 9) {
disp += "0" + secs;
} else {
disp += secs;
}
return(disp);
}
function redo() {
secs--;
if(secs == -1) {
secs = 59;
mins--;
}
document.getElementById("disp").innerHTML=dis(mins,secs); // setup additional displays here.
if((mins == 0) && (secs == 0)) {
window.alert("Time is up. Press OK to continue."); // change timeout message as required
// window.location = "yourpage.htm" // redirects to specified page once timer ends and ok button is pressed
} else {
cd = setTimeout("redo()",1000);
}
}
function init() {
cd();
}
window.onload = init;
</script>

If the page is refreshed, all you javascript code is re-executed. This is normal behaviour.
If you absolutely need to continue where you left, you can use the local storage API (only available in modern browsers) to store the time (every second you update the value).
When the page is loaded, you can then check if the value exists in Local storage, and start from where you were.
Are you sure you need this behaviour BTW?

Related

Countdown on Ionic 2

ionViewDidEnter() {
//----------------------------------------------------------------------LISTAGEM ALMOÇOS--------------------------------------------------------------------------------------
let data = JSON.stringify({id: this.id});
let link = *;
this.http.post(link,data)
.map(res => res.json())
.subscribe(data=>{
console.log(data);
this.almocos = [];
//IDs das conversas
for (var a = 0; a < data.length; a++){
this.foto2 = data[a][2];
if(Number.isInteger(data[a][7])){
console.log(data[a][7])
this.tempo[0] = data[a][7] + "dias"
this.tempo[1] = "";
this.tempo[2] = "";
}else {
this.tempo = data[a][7].split(":");
this.tempo[0] = this.tempo[0] + ":";
this.tempo[1] = this.tempo[1] + ":"
}
this.tempos = [];
this.foto =[];
let cor;
let pessoas;
let forma;
if (data[a][4].length == 1){
if(data[a][5]== this.nome){
data[a][2]= data[a][4][0][1]
}
pessoas = data[a][4][0][0];
this.foto.push(data[a][4][0][1]);
} else if (data[a][4].length == 2) {
pessoas = data[a][4][0][0] + " e " + data[a][4][1][0];
this.foto.push(data[a][4][0][1]);
this.foto.push(data[a][4][1][1]);
} else {
pessoas = data[a][4][0][0] + " e " + (data[a][4].length-1) + " pessoas"
for (var i = 0; i < data[a][4].length; i++){
this.foto.push(data[a][4][i][1]);
}
}
if(data[a][4].length > 1){
if(data[a][6] == 1){
data[a][2] = "social.png";
cor= "#e73C58";
forma = "S"
} else if (data[a][6] == 2){
data[a][2] = "profissional.png";
cor= "#1ab2bc";
forma = "P";
}else if (data[a][6] == 3){
data[a][2] = "academico.png";
cor= "#9b59b6";
forma = "A";
}
}else{
if(data[a][6] == 1){
cor= "#e73C58 ";
forma = "S"
} else if (data[a][6] == 2){
cor= "#1ab2bc ";
forma = "P";
}else if (data[a][6] == 3){
cor= "#9b59b6";
forma = "A"
}
}
this.cores = "#ffffff";
this.almocos.push(
{
id : data[a][0],
dia : data[a][1],
foto : data[a][2],
foto_anf: this.foto2,
estrelas : data[a][3],
pessoal : pessoas,
tipo : cor,
forma :forma,
fotos : this.foto,
segundo : this.tempo[2],
minuto : this.tempo[1],
horas : this.tempo[0]
});
setInterval(function(){
console.log("segundos");
let segundos;
let minutos;
let hora;
segundos--;
if (segundos == 0){
segundos = 60;
minutos--;
}
if (minutos == 0){
minutos = 59;
hora--;
}
segundos-- ;
this.tempos = [];
this.tempos.push(segundos);
}, 1000);
}
}, error =>{
console.log("erro")
});
//----------------------------------------------------------------------FIM LISTAGEM ALMOÇOS--------------------------------------------------------------------------------------
}
<div style="float:right;position:relative;left:0px;position:relative;top:3px">
<span><ion-icon style="font-size:14px;" name="md-time"></ion-icon><span style="font-size:13px;position:relative;bottom:1px;margin-left:2px"> {{almoco.horas}}{{almoco.minuto}}{{almoco.segundo}} </span></span>
</div>
The variables are hours, minutes and seconds. Each is related to a date in the database, where we get the time remaining. I'd like to be able to show in real-time a countdown until the actual date.
I know it's possible via Observable, but I can't figure out how. An answer with integer variables (e.g. hours= 23; minutes=14; seconds=19) would be ideal, so I can just attribute the values from the database.
Thanks in advance!
I noticed some issues in your code that could help you to solve your problem:
You should avoid to change the data object itself and instead create a copy and work with that. That way you always know what the server responded with and what you changed.
You have a lot of "hardcoded" array indexes. If you have control over the backend, you should try to avoid that and instead use an object with named properties. So instead of doing
this.push(data[a][4][0][1]);
you could do something like
data[a].almoco.photoUrl // Depending on what you want to do, obviously
which looks a lot nicer and gives you more readable code.
Now to your countdown problem:
First of all, you have your setInterval inside your for loop, which means that the setInterval is called multiple times per second. (At least as many times as you have elements in your array).
You also define
let segundos;
let minutos;
let hora;
but never assign them a value, so your if-checks will always be wrong.
You should also avoid calculating the time when you get the response from the server and instead store the end-time you get from the server as a javascript date.
Once you have that, you can either calculate the difference manually in your setInterval (end-date - current date, make sure you call it only once) and use a custom angular pipe to convert the seconds to a nice format, or use an npm nodule like this: https://github.com/previousdeveloper/angular2-simple-countdown

Javascript Application is crashing every 4-5 hrs in chrome and firefox

My application is crashing every 4-5 hrs and I am not sure it is happening because of memory leak or any code performance issue.
I have 3-4 functions which have timeouts to call self every 5 sec and they does some data massaging before painting the DOM.
As you can see my snapshots keep on increasing every time I take new snapshot.
Unable to find what exactly is happening. But if we look at the snapshots we can say that the strings has been increasing significantly from snapshot 1 to snapshot 9.
Any help is appreciated.
Sample code:
function fetchSummary() {
if(!$rootScope.pageVisible) {
$scope.fetchSummaryTimeout = $timeout(fetchSummary, 1000);
$scope.lastRefreshedDateTime = new Date();
return;
}
$http
.get(apiUri + '/statusboard/api/summaryDb')
.success(function (response) {
if (response && response.length) {
$scope.databases = response[0];
$scope.fetchSummaryTimeout = $timeout(fetchSummary, 5000);
var i, j, l;
//alert counts
angular.forEach($scope.databases.summary, function (summary) {
if (summary.eventType === "database_connection_alert") {
$scope.connectionCount += summary.count;
}
if (summary.eventType === "database_session_alert" || summary.eventType === "database_load_alert") {
$scope.warnCount += summary.count;
}
});
for (l = 0; l < $scope.databases.components.length; l++) {
var component = $scope.databases.components[l];
//some data stuff
for (j = 0; j < component.summary.length; j++) {
var summary = component.summary[j];
}}
$scope.coloCounts.any = $scope.coloCounts.All + $scope.coloCounts.lvs + $scope.coloCounts.slc + $scope.coloCounts.phx;
for (i = 0; i < $scope.databases.vcsStatus.length; i++) {
//Some stuff
}
}
} else {
$scope.fetchSummaryTimeout = $timeout(fetchSummary, 5000);
}
angular.element("#last-updated, #last-updated-overlay").remove();
})
.error(function () {
$scope.fetchSummaryTimeout = $timeout(fetchSummary, 5000);
});
}
}
"$scope.databases" is the variable every time i set the response to.

Add cookie / no-repeat function to random page refresh

I have been using this java code to call a random html page from a list of 49 on a set timer (or upon page refresh). I would like to convert it so that a cookie - or something else - saves the pages that have already been shown so that upon refresh the user always receives a new page, until the list is finished, at which point the cookie is emptied/deleted.
I found this code for a cookie image array. Could I use it with this? A variant of this also appears here. Apologies, my coding is pretty poor. Any advice appreciated:
<script type="text/javascript">
var sites = [
"name1.html",
"name2.html",
"name3.html",
"name...etc.html",
"name49.html",
]
$(document).ready(function() {
newPage();
});
function newPage()
{
setTimeout(newPage, 60000);
var min = 0;
var max = 48;
var num = Math.floor(Math.random() * (max - min + 1)) + min;
$('#target').attr('src',sites[num]);
}
</script>
var numSites = 49;
var seen = new Array(numSites);
$(document).ready(function() {
var cookie = unescape(getCookie("seen"));
seen = cookie ? cookie.split(',') : seen;
setTimeout(gotoNext, 60000);
});
function gotoNext() {
var num = getRandom();
var count = 0;
while (seen[num] == 1) {
num++;
if (num >= numSites) {
num = 0;
count++;
if (count > 1) {
resetSeen();
num = getRandom();
}
}
}
seen[num] = 1;
setCookie("seen", escape(seen.join(',')), 365);
window.location = "name" + num + ".html";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name)==0) return c.substring(name.length, c.length);
}
return "";
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
function resetSeen() {
for (var i=0; i<numSites; i++) {
seen[i] = "";
}
}
function getRandom() {
return Math.ceil(Math.random() * numSites);
}
It looks like you're using jQuery so I'll recommend using a jquery plugin for managing cookies much more neatly.
Copy & paste the contents of this URL to a new js file on your server and include it after the jquery file: https://raw.githubusercontent.com/carhartl/jquery-cookie/master/jquery.cookie.js
Or you could possibly use the get/set cookie functions from the other answer you mention.
The main thing to remember is that the cookie is stored as a string so you'll be join()ing and split()ing the array.
The other thing to note is that because we want a random item from the items we haven't visited yet it's more efficient to keep track of those rather than the ones we have visited.
What this means is we always choose a random item from what's left instead of looping over everything and checking each time if we've been there already as that would get very inefficient.
var sites = [ 'name1.html', 'name2.html', 'name3.html', ...etc... ],
unvisited = sites.slice(0); // .slice(0) clones the array
// if the cookie has a value then make it into the unvisited array
if ( $.cookie( 'unvisited' ) )
unvisited = $.cookie( 'unvisited' ).split( ',' );
$(document).ready(function() {
newPage();
});
function newPage() {
setTimeout( newPage, 60000 );
// check if the unvisited array needs resetting
if ( unvisited.length == 0 ) {
unvisited = sites.slice(0);
$.removeCookie( 'unvisited' );
}
// get a new index from the unvisited array
var num = Math.floor( Math.random() * unvisited.length );
// remove the item from the array and save the cookie
var site = unvisited.splice( num, 1 )[ 0 ];
// save the unvisited array minus the site we just spliced out
$.cookie( 'unvisited', unvisited.join( ',' ) );
$( '#target' ).attr( 'src', site );
}

Angular - Delaying forEach

I have a problem. I am trying to create an animation, changing the color of several layers with a timeout between painted.
$scope.StartMovementsAnimation = function()
{
angular.forEach($scope.GameMovements, function(movement){
if (movement == "Green")
{
$scope.Green = true;
}
else (movement == "Orange")
{
$scope.Orange = true;
}
});
}
The problem I have is that I do not know how to stop or delay the flow loop. I'm pretty lost. I tried with $ timeout, sleep etc but does not work.
Any solution?
thanks
Don't use forEach. Use $timeout to repeat as many as the number of items in your GameMovements array.
Take a look at the following example. It is going to change className field from orange to green and vice versa till the variable left's value reaches 0.
$scope.className = "orange";
$scope.count = 0;
$scope.startAnimation = function() {
var left = 10
var ticker = function() {
if (left % 2 === 0)
$scope.className = 'orange'
else
$scope.className = 'green'
left -= 1
if (left > 0) {
$timeout(ticker, 1000)
}
}
$timeout(ticker, 1000)
}

Issues with using setTimeout inside of a for loop with arrays

--- UPDATE ---
Here is another attempt... The issue seems to be that the animation only happens to the third item in the for loop array I'm assuming because of the setTimeout delay. How can I have the animation fire for each item (3) with a delay?
// Breadcrumb Animation
(function(){
var header = document.getElementById("header"),
header2 = document.getElementById("header-secondary"),
banner = document.getElementById("banner");
var bcLink = [header, header2, banner];
var myTime = '';
var myItem = '';
function delay() {
setTimeout(fadeIn, myTime);
function fadeIn() {
if( myItem.style.opacity !== '1' ) {
console.log(myItem);
setInterval(function(){
myItem.style.opacity = parseFloat(myItem.style.opacity) + 0.1;
}, 100);
}
}
}
var i, len=bcLink.length;
for(var i = 0; i < len; i++) {
bcLink[i].style.opacity = 0;
myItem = bcLink[i];
myTime = myTime = parseInt(myTime + 2000)
delay();
}
})();
--- END UPDATE ---
The code below works but I was trying to optimize my code by creating a foor loop that will loop through each of the items (my attempt is commented out). I'm currently using 3 items on my page (header, header2, banner) that will load one after the other, but the second should not start until the first loads, the third should not start until the second item loads, and so on. This code will eventually be used for breadcrumbs where the amount of items will be uncertain but they will still load one after the other. Any help is greatly appreciated.
(function(){
var header = document.getElementById("header"),
header2 = document.getElementById("header-secondary"),
banner = document.getElementById("banner");
var bcLink = [header, header2, banner];
var myTime = '';
function fadeIn(name, speed) {
if( name.style.opacity !== '1' ) {
setInterval(function(){
name.style.opacity = parseFloat(name.style.opacity) + 0.1;
}, speed);
}
}
function delay(funct, time) {
setTimeout(function() {funct}, time);
}
bcLink[0].style.opacity = 0;
bcLink[1].style.opacity = 0;
bcLink[2].style.opacity = 0;
setTimeout(function(){fadeIn(bcLink[0], 100)}, 0);
setTimeout(function(){fadeIn(bcLink[1], 100)}, 1000);
setTimeout(function(){fadeIn(bcLink[2], 100)}, 2000);
// for(var i = 0; i < bcLink.length; i++) {
// bcLink[i].style.opacity = 0;
// delay(fadeIn(bcLink[i],100), i + 000);
// }
})();
use jQuery animation queue, not timeout.
http://blog.bigbinary.com/2010/02/02/understanding-jquery-effects-queue.html
Try changing:
delay(fadeIn(bcLink[i],100), i + 000);
to:
setTimeout(function(){fadeIn(bcLink[i], 100)}, i * 1000);

Resources