localstorage not persisting on node-webkit - javascript

I'm working on a NW.js (Node-Webkit) app and I noticed that the local storage objects I'm using aren't persisting.
The problem is simple I guess, data gets saved in a local storage object then when a window.open window is opened it should print that saved data, but when I open the dev tools I notice only the name of the local storage object which is "view" exists but the value is empty (undefined). What's irritating is that it works perfectly well from the browser (chrome, firefox, etc..).
This is my code
var count = 3600,
counter,
seconds,
minutes,
startGameBtn = document.getElementById('start-game-btn'),
slaveScreen = document.getElementById('slave-screen');
//When this button is pressed a count down starts from 1 hour
startGameBtn.addEventListener('click', function() {
counter = setInterval(timer, 1000);
GameplayStatus = true;
if (GameplayStatus) {
this.disabled = true;
}
function timer() {
count = count - 1;
if (count == -1) {
clearInterval(counter);
return;
}
seconds = count % 60;
minutes = Math.floor(count / 60);
minutes %= 60;
masterScreen.innerHTML = minutes + ":" + seconds;
localStorage.setItem('view', minutes + ":" + seconds);
}
});
//In order to recognize the new window and be able to target it
if (location.hash) {
setInterval(function() {
//should print the timer in the new window constantly. Works perfectly on the browser but doesn't display anything on node-webkit. The key exists but the value is empty (undefined)
slaveScreen.innerHTML = localStorage.getItem('view');
}, 50);

Related

Fixing double running of javascript code in different tabs

I created a little timer which runs from 30seconds down to 0 and saved in the localStorage, butthen restarts after a event and again begins at 30secs. But if I open 2 tabs of the same page the code runs double. That means that after 1 seconds the timer jumps for example from 30 to 28.
function timer(){
localStorage.setItem("time", 30);
setInterval(function(){
localStorage.setItem("time", localStorage.getItem("time") - 1);
timerPlace.innerHTML = localStorage.getItem("time");
if(localStorage.getItem("time") < 0){
localStorage.setItem("time", 0);
timerPlace.innerHTML = "TIME TO PLACE !";
}
}, 1000);
if(localStorage.getItem("time") === null){
localStorage.setItem("time", 30);
}
}
I already thought of getting the number of opened tabs and do something with this. Or maybe there is a way to only run a javascript code in one tab.
Store the start time of your count in localStorage. Then calculate the distance from it in seconds. when reach 30, clear that value.
This example is without using localStorage because not allowed in a stack snippet.
var start = (new Date()).getTime();
var ind_id
ind_id = setInterval(function() {
var now = (new Date()).getTime()
var diff_in_seconds = Math.round((now - start) / 1000)
if (diff_in_seconds >= 30) {
cancelInterval(ind_id)
return;
}
timerPlace.innerHTML = (30 - diff_in_seconds)
}, 1000)
<div id="timerPlace"></div.>

Create a timer which resets itself after 24 hours but doesn't get restarted after the page is reset

i'm creating a web app and i'm trying to create a countdown timer for a certain product that is on discount and i'm wondering if there is a way to not reset the timer after the page has been refreshed and when it reaches 0 , wait 24 hours and then reset itself automatically. Here is a picture of a timer down below:
Here is the code of a timer:
var count = 420;
var counter = setInterval(timer, 1000);
function timer() {
count = count - 1;
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
minutes %= 60;
document.getElementById("timer").innerHTML = (minutes).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}) + ":" + (seconds).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); // watch for spelling
document.getElementById("timer2").innerHTML = (minutes).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}) + ":" + (seconds).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); // watch for spelling
}
It's not a great option, but when the user first lands on the page, create a timer with a new count down and store the counter value in the local storage, and update it every second in the storage as well.
And the next time the user comes, you can check if you already have the counter in the storage, use that value of the counter to create the timer.
Here's some documentation on using localStorage - https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
You can use localStorage to persist a value across page loads. When talking about a timer, it makes sense to save the time at which the timer was started. That way when a visitor comes back your code can tell exactly how much time is left on it.
// Get the time stamp (in milliseconds) that the timer started
var timerStart = window.localStorage.getItem('timerStart')
if (!timerStart){
// If a timer was never started, start one
timerStart = new Date().getTime()
window.localStorage.setItem('timerStart', timerStart)
}
// Update the timer every 1/10th of a second
setInterval(timer, 100);
function timer() {
// Use the start time to computer the number of
// seconds left on the timer
var count = 7 * 60 - Math.round((new Date().getTime() - timerStart) / 1000)
if (count < 0) {
clearInterval(timer);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
minutes %= 60;
document.getElementById("timer").innerHTML = (minutes).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}) + ":" + (seconds).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
}

setInterval halted when I move between browser tabs in react [duplicate]

function initTimer(timeLeft) {
var Me = this,
TotalSeconds = 35,
Seconds = Math.floor(timeLeft);
var x = window.setInterval(function() {
var timer = Seconds;
if(timer === -1) { clearInterval(x); return; }
$('#div').html('00:' + (timer < 10 ? '0' + timer : timer));
Seconds--;
},1000);
}
I have this code. Everything works fine, when this tab is active in browser, but when I change tab and return in tab later it has problems. To be more precise, it Incorrectly displays the time.
I'd also tried setTimeout, but problem was the same.
One idea, which I have is: HTML5 Web Workers...
But here is another problem... browsers support.
can someone help to solve this problem?
How can I write setInterval, which works properly,even when tab is not active
Use the Date object to calculate time. Don't rely on a timer firing when you ask it to (they are NOT real-time) because your only guarantee is that it'll not fire before you ask it to. It could fire much later, especially for an inactive tab. Try something like this:
function initTimer(periodInSeconds) {
var end = Date.now() + periodInSeconds * 1000;
var x = window.setInterval(function() {
var timeLeft = Math.floor((end - Date.now()) / 1000);
if(timeLeft < 0) { clearInterval(x); return; }
$('#div').html('00:' + (timeLeft < 10 ? '0' + timeLeft : timeLeft));
},200);
}
initTimer(10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div"></div>
Note that by checking it more frequently we can make sure it's never off by too much.
JavaScript timers are not reliable, even when the tab is active. They only guarantee that at least as much time as you specified has passed; there is no guarantee that exactly that amount of time, or even anything close to it, has passed.
To solve this, whenever the interval fires, note what time it is. You really only need to keep track of two times: the current time, and the time that the previous interval fired. By subtracting the previous tick's time from the current tick's time, you can know how much time has actually passed between the two, and run your calculations accordingly.
Here's a basic outline of how something like this might look:
function initTimer(timeLeft) {
var Me = this,
TotalSeconds = 35,
Seconds = Math.floor(timeLeft),
CurrentTime = Date.now(),
PreviousTime = null;
var x = window.setInterval(function() {
var timer = Seconds,
timePassed;
PreviousTime = CurrentTime;
CurrentTime = Date.now();
timePassed = CurrentTime - PreviousTime;
if(timer < 0) { clearInterval(x); return; }
$('#div').html('00:' + (timer < 10 ? '0' + timer : timer));
Seconds = Seconds - timePassed;
},1000);
}

Countdown timer 'delays' when tab is inactive?

Trying to build a very simple Javascript countdown. However, whenever the tab is inactive, the countdown begins to lag and holds an incorrect count.
See jsfiddle here for example: https://jsfiddle.net/gbx4ftcn/
function initTimer(t) {
var self = this,
timerEl = document.querySelector('.timer'),
minutesGroupEl = timerEl.querySelector('.minutes-group'),
secondsGroupEl = timerEl.querySelector('.seconds-group'),
minutesGroup = {
firstNum: minutesGroupEl.querySelector('.first'),
secondNum: minutesGroupEl.querySelector('.second')
},
secondsGroup = {
firstNum: secondsGroupEl.querySelector('.first'),
secondNum: secondsGroupEl.querySelector('.second')
};
var time = {
min: t.split(':')[0],
sec: t.split(':')[1]
};
var timeNumbers;
function updateTimer() {
var timestr;
var date = new Date();
date.setHours(0);
date.setMinutes(time.min);
date.setSeconds(time.sec);
var newDate = new Date(date.valueOf() - 1000);
var temp = newDate.toTimeString().split(" ");
var tempsplit = temp[0].split(':');
time.min = tempsplit[1];
time.sec = tempsplit[2];
timestr = time.min + time.sec;
timeNumbers = timestr.split('');
updateTimerDisplay(timeNumbers);
if (timestr === '0000')
countdownFinished();
if (timestr != '0000')
setTimeout(updateTimer, 1000);
}
function animateNum(group, arrayValue) {
TweenMax.killTweensOf(group.querySelector('.number-grp-wrp'));
TweenMax.to(group.querySelector('.number-grp-wrp'), 1, {
y: -group.querySelector('.num-' + arrayValue).offsetTop
});
}
setTimeout(updateTimer, 1000);
}
I'm unsure whether the problem lies with the animation, or with the JS code itself.
For clarification: I want the countdown to continue when the tab is inactive, or to 'catch up with itself' when the tab comes back in to focus.
I know that setTimeout and setInterval can cause issues with inactive tabs, but I'm not entirely sure how to fix this.
Any help would be much appreciated!
For this you can use the HTML5 Visibility API for detecting if the browser tab is active or not. And use regular binding of event handlers for focus and blur for the browser window.
Basically you pause() the timeline when you blur out of the tab, and then play() when you give the tab refocus. Example of this in action:
http://codepen.io/jonathan/pen/sxgJl
// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
// If the page is hidden, pause the video;
// if the page is shown, play the video
function handleVisibilityChange() {
if (document[hidden]) {
tl.pause();
} else {
tl.play();
}
}
// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") {
// do nothing or throw error via alert()
alert("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
// Handle page visibility change
// Pause timeline
tl.pause();
}
HTML5 Visibility Docs:
https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
Regarding GreenSock Forum Topic:
http://forums.greensock.com/topic/9059-cross-browser-to-detect-tab-or-window-is-active-so-animations-stay-in-sync-using-html5-visibility-api/
Also in GSAP the equivalent for setTimeout() is delayedCall()
Provides a simple way to call a function after a set amount of time (or frames). You can optionally pass any number of parameters to the function too.
GSAP delayedCall(): http://greensock.com/docs/#/HTML5/GSAP/TweenMax/delayedCall/
//calls myFunction after 1 second and passes 2 parameters:
TweenMax.delayedCall(1, myFunction, ["param1", "param2"]);
function myFunction(param1, param2) {
//do stuff
}
I hope this helps!
before all, i have to mention that, those countdown animation is truly outstanding and elegant dear sir! well done...
Now to the answers:
as mentioned in many articles, and here is one of them:
setInterval(func, delay) does not guarantee a given delay between
executions. There are cases when the real delay is more or less than
given. In fact, it doesn’t guarantee that there be any delay at all.
Source: http://javascript.info/tutorial/settimeout-setinterval
and..
Most browsers apply performance improvements by reducing the priority
of several tasks on inactive tabs or even some portions of the page
that aren't on screen. Sometimes these improvements affects the
executions of Javascript intervals as well.
Source: How can I make setInterval also work when a tab is inactive in Chrome?
as you can see, they mentioned that setInterval does not guarantee a given delay between executions even when the tab is active, and lets just assume that setTimeout (the one that you used) is also the same because they are relatively is "the same"
so what is the solution to this problem?
well, what you actually can do is check how many times has actually elapsed between the event, something like this Codepen
EDIT: as you have requested, here is a fiddle of your countdown with the fix, and i have //commented on the changes i made to the fiddle, so it would hopefully make it easier for you to understand. So now, when you paired the countdown to other timer (ex. your phone's timer) you should get the same result even when the tab is inactive or the frame rate slowdown.
if you have enjoyed my answer please consider mark it as "the answer" or at least up vote it ;)
The simplest way to ensure the timer stays correct when a user moves off the tab and then returns is to use session storage - to store the original starting time:
on the first load - get the local current datetime and store into session storage (note that will only accept a string - so you will have to stringify the value and then parse it out again upon retrieval).
when the tab loses focus that set start time will still be stored as startTime in ss. When the tab regains focus - have a function that gets the new current datetime, gets the stored datedtime from session storage and calculates the difference. Then the timer can be updated to the new reduced time.
Eg if its 10:00 am on page load - set the startTime into ss. Then the user spends 1 minute on the site and goes offsite for 5 minutes. Upon returning - the above described process will determine the current time is 10:06 and determine that its 6 minutes later than the start time so can update the timer as such.
This avoids the need for intervals and timers etc. You can take the specificity down to ms if needed. And also - I like your fiddle too.
You can use this code. Each time the tab changes, it calculates the end time again and updates the counter.
let interval;
let duration=timeDifference(endTime(),nowDate())
updateTime();
$(window).focus(function () {
clearInterval(interval)
updateTime();
});
function updateTime() {
interval = setInterval(function () {
var timer = duration.split(':');
//by parsing integer, I avoid all extra string processing
var hours = parseInt(timer[0], 10);
var minutes = parseInt(timer[1], 10);
var seconds = parseInt(timer[2], 10);
--seconds;
minutes = (seconds < 0) ? --minutes : minutes;
if (minutes < 0) clearInterval(interval);
seconds = (seconds < 0) ? 59 : seconds;
seconds = (seconds < 10) ? '0' + seconds : seconds;
hours = (hours < 10) ? '0' + hours : hours;
//minutes = (minutes < 10) ? minutes : minutes;
$('.countdown').html(hours + ':' + minutes + ':' + seconds);
duration = hours + ':' + minutes + ':' + seconds;
}, 1000);
}
function nowDate() {
let date = new Date()
let time1 = new Date();
date = date.toISOString().slice(0, 10);
date = date.split('-');
return new Date(date[2] + '/' + date[1] + '/' + date[0] + " " + time1.getHours() + ":" + time1.getMinutes() + ":" + time1.getSeconds());
}
function endTime() {
let endTime = $('input[name=end_date]').val();
endTime = endTime.split(' ');
let date = endTime[0].split('-');
let time = endTime[1];
return new Date(date[2] + '/' + date[1] + '/' + date[0] + " " + time);
}
function timeDifference(date1,date2) {
var difference = date1.getTime() - date2.getTime();
var daysDifference = Math.floor(difference/1000/60/60/24);
difference -= daysDifference*1000*60*60*24
var hoursDifference = Math.floor(difference/1000/60/60);
difference -= hoursDifference*1000*60*60
var minutesDifference = Math.floor(difference/1000/60);
difference -= minutesDifference*1000*60
var secondsDifference = Math.floor(difference/1000);
return hoursDifference +":"+minutesDifference+":"+secondsDifference
}

How to automatically reload a web page at a certain time?

I have a website that I want to be reloaded at a certain time, like 3:35pm, not after a specific interval like 5min. How do I do that?
The following JavaScript snippet will allow you to refresh at a given time:
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);
}
Then you can add a script tag to call the refreshAt() function.
refreshAt(15,35,0); //Will refresh the page at 3:35pm
Note that this code will refresh based on the client local time. If you want it to be at a specific time regardless of the client's timezone, you can replace get*() and set*() (except getTime()) on the time objects with their getUTC*() and setUTC*() equivalent in order to pin it to UTC.
<META HTTP-EQUIV="Refresh" CONTENT="5">
this will force page to reload every 5 seconds. Just calculate the correct interval and add it to content tag
I found this page with a similar question and used it to hack out a more specific answer that may be of use to some. For this project, we wanted to make sure that the page refreshed once a live event of global interest was about to go on, activating the player embed on the user's page (narrow use case, I know -- others might have a better use for it).
One challenge in the above answers was how to deal with time zone conversions, which was more of an issue for us because we wanted to make sure that the page refreshed at a specific day and time. To do this, I grabbed a UTC version of the target date and today's date, converted them to GMT, then set Andrew's timeout function to the difference between the two.
var target = new Date("January 28, 2011 13:25:00");
timeOffset = target.getTimezoneOffset() * 60000;
targetTime = target.getTime();
targetUTC = targetTime + timeOffset;
var today = new Date();
todayTime = today.getTime();
todayUTC = todayTime + timeOffset;
refreshTime = (targetUTC - todayUTC);
if (refreshTime > 1) {
setTimeout(function() { window.location.reload(true); }, refreshTime);
}
Basically, when the page is accessed, calculate how much time is remaining between the access time and the time you want to reload the page, and use that remaining time in the meta refresh header. Obviously this would need to be done in a CGI script or web application, or possibly with SSI (server-side includes); it won't work if all you have is a static HTML file.
Another alternative would be to use Javascript, but it won't work if the client has Javascript disabled.
This worked better for my purposes.
If you're able to use Jquery and MomentJs, you can do this:
(function () {
var $ = require('jquery');
var moment = require('moment');
function refreshPageAtTime(expiration, countdownElement) {
var now = moment.utc();
console.log('now', now);
var expirationMoment = moment.utc(expiration, 'YYYY-MM-DD kk:mm:ss');
console.log('target', expirationMoment);
var secondsUntilRefresh = expirationMoment.diff(now, 'seconds');//http://momentjs.com/docs/#/displaying/difference/
console.log('diff in seconds', secondsUntilRefresh);
if (secondsUntilRefresh > 1) {
setInterval(function () {
secondsUntilRefresh--;
console.log('seconds remaining', secondsUntilRefresh, 'seconds');
if (secondsUntilRefresh <= 10) {
countdownElement.html(secondsUntilRefresh + '...');
if (secondsUntilRefresh === 0) {
console.warn('Refreshing now at ' + moment.utc());
window.location.reload(true);
}
}
}, 1000 * 1);
}
}
$(document).ready(function () {
var expiration = $('form').attr('data-expiration');
console.log('expiration', expiration);
$('.btn-primary:submit').after('<div id="countdownToRefresh" style="display: inline-block; color: #999; padding: 10px;"></div>');
refreshPageAtTime(expiration, $('#countdownToRefresh'));
});
})();
Basically, there are many javascript codes out there that can refresh the page ever so minutes or something, you can edit them to refresh at hours too. Like this one:
//enter refresh time in "minutes:seconds" Minutes: 0 to Whatever
//Seconds should range from 0 to 59
var limit = "0:30";
if (document.images) {
var parselimit = limit.split(":");
parselimit = parselimit[0] * 60 + parselimit[1] * 1;
}
var beginrefresh = function () {
if (!document.images) return if (parselimit == 1) window.location.reload()
else {
parselimit -= 1;
curmin = Math.floor(parselimit / 60);
cursec = parselimit % 60;
if (curmin != 0) curtime = curmin + " minutes and " + cursec + " seconds left until page refresh!";
else curtime = cursec + " seconds left until page refresh!";
window.status = curtime;
setTimeout("beginrefresh()", 1000);
}
}
window.onload = beginrefresh;
(now just calculate the minutes and seconds you want it to refresh, like for example noon everyday if it were noon now:
var limit = "1440:00";
Now you could use this code except, most of them don't work with server time, And with the information you provided us, we really can't do anything more. Edit your question and tell us if you want it to be timed with the servers time, or something else.
I hope this help,you can set the exact time for refresh
var target = new Date("November 18, 2019 10:00:00");
timeOffset = target.getTimezoneOffset() * 60000;
targetTime = target.getTime();
targetUTC = targetTime + timeOffset;
var today = new Date();
todayTime = today.getTime();
todayUTC = todayTime + timeOffset;
refreshTime = (targetUTC - todayUTC);
if (refreshTime > 1) {
setTimeout(function() { window.location.reload(true); }, refreshTime);
}
if you using Flask you can set variable synchronized to network time. In the flash app
from datetime import *`
def syncRefresh():`
while (datetime.now().second % 10 !=0):`
continue`
return True`
and #app.route('/', methods =["GET"})
def table():
....
if syncRefresh():
refreshNow = True # refreshNow is the variable passed to the web page
and in the html page
{% if refreshNow %}
<meta http-equiv="refresh" content="1">
{% endif %}
refresh at a given minute and second → i.e. every hour at fixed time can be as follows:
<script type="text/javascript">
function refreshAt(minute, second) {
var date= new Date();
var hr = date.getHours();
var m = date.getMinutes();
var s = date.getSeconds();
if(m == minute && s == second)
{
window.location.reload(true);
}
setTimeout(function() { refreshAt(minute, second); },600);
};
</script>
Use this to refresh the page every 20 seconds.
<META HTTP-EQUIV="refresh" CONTENT="20">

Categories