Timer that keeps counting when navigating away from page - javascript

I have a timer that counts down once a specific page is visited. I need this timer to keep counting even if someone goes to a different page, and maintain the time counted to display it on the screen when they return to the original page where it was triggered.
The code I have in place is
<script>
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 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 "";
}
//check existing cookie
cook=getCookie("test9_cookie");
if(cook==""){
//cookie not found, so set seconds=60
var seconds = '<?php echo OFFERTIME ?>';
}else{
seconds = cook;
console.log(cook);
}
// init var
var timeout = 0;
// end init var
function secondPassed() {
var minutes = Math.round((seconds - 30)/60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
//store seconds to cookie
setCookie("test9_cookie",seconds,1); //here 1 is expiry days
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
timeout = 1;
sessionStorage.setItem('nothanks', 1);
document.getElementById('timed-over').style.display = "block";
$("#timed-over").delay(4800).fadeOut(300);
document.getElementById('timed-container').style.display = "none";
} else {
seconds--;
}
}
var countdownTimer = setInterval(secondPassed, 1000);
//localStorage.removeItem('timedpid') //to delete localstorage during testing
function checktaken(){
if(timeout===1) {
//do nothing as expired
}else if(localStorage.getItem('timedpid')) {
var storedpid = localStorage.getItem('timedpid')
var currentpid =<?php echo json_encode($time_limited_pid); ?>;
if (storedpid !== currentpid) {
var showOffer = document.querySelector("#timed-container");
showOffer.style.display = "block";
}
}else if(sessionStorage.getItem('nothanks')) {
// do nothing as offer not wanted
}else{
var showOffer = document.querySelector("#timed-container");
showOffer.style.display = "block";
}
}
setInterval('checktaken()',1);
</script>
Is there any way to make the original code keep counting when the page the script is on is navigated away from?
If not, a solution would be to move part of the script to the header and have it only load when on a specific page. Doing this would mean having to pass a var from the script in the header, to a script in a different file. I'm not too clued up on javascript and haven't had any luck sharing variables across multiple pages before.

Stuff the start time into the cookie (or local storage, anything permanent) and use the difference between that start time and the current time for your timer.

Related

How to disable popup from showing up on given page for 2 days after I click .popup-close on first visit to that page?

How to disable popup from showing up on given page for 2 days after I click .popup-close on first visit to that page ?
This is my code https://jsfiddle.net/4q1aL8pL/2/
I've tried localstorage between lines 122-140 in my code. I am javascript beginner please help :)
Maby there has to be some timer applied which will count to 2 days hours worth ?
//<![CDATA[
var n = Number(localStorage.getItem('odometerValue')) || 0;
var m = localStorage.getItem('displayNone');
var myOdometer;
function startcounting () {
var div = document.getElementById("odometerDiv");
myOdometer = new Odometer(div, {value: n, digits: 6, tenths: true});
myOdometer.set(n);
update();
}
function update () {
n=n+0.01
myOdometer.set(n);
localStorage.setItem('odometerValue', n);
localStorage.setItem('displayNone', m);
setTimeout(update, 200);
}
//]]>
you can use the local storage to save the date of when the pop up loaded.
var d = new Date();
this will stamp the current date then all you have to do is check with the date of the visitor again and if you minus them and it equals 2 days pop up again.
Here is a function for using cookies.
/* Show popup if cookie doesn't exist. Will hide for 2 days if closed */
var PopUpCookie = getCookie("MyPopUpCookie");
if (PopUpCookie == '') {
$('#odometerDiv').show();
} else {
$('#odometerDiv').hide();
}
}
$('.popup-close').on('click', function () {
$('#odometerDiv').hide();
setCookie("MyPopUpCookie", "hide");
});
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (2*24*60*60*1000)); /* 2 days */
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
function getCookie(cname) {
var name = cname + "=";
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);
if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
}
return "";
}

JavaScript - Delay execution of certain javascript

I need help in delaying the execution of my javascript.(not making the javascript to execute right after the webpage is being loaded) I wish to execute the javascript only after 10s after the webpage is being loaded. How can I do that? This is the script.
<script>
var interval = 10000;
var current_index = -1;
var sales_feeds = [];
var showtime = 5000;
<?php $s = get_option('wc_feed_delay_between_popups_appear');
if (!$s) {
$s = 5000;
}
?>
function hide_prev_feed_notify(index)
{
if( sales_feeds.eq(current_index).length > 0 )
{
sales_feeds.eq(current_index).animate({bottom: '-90px'}, 500);
}
}
function show_live_feed_notify(index)
{
sales_feeds.eq(index).animate({bottom: '10px'}, 1000);
current_index = index;
}
function show_next_live_notify()
{
if( (current_index + 1) >= sales_feeds.length )
{
current_index = -1;
}
//add randomness
current_index = (Math.floor(Math.random() * (sales_feeds.length + 1))) - 1;;
if( window.console )
console.log('will show ' + (current_index+1));
show_live_feed_notify(current_index + 1);
setTimeout(function() { hide_prev_feed_notify(current_index + 1); }, showtime);
}
function stop_live_notify()
{
removeInterval(inverval);
}
function readCookie(name)
{
var nameEQ = escape(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 unescape(c.substring(nameEQ.length, c.length));
}
return null;
}
jQuery(function()
{
jQuery('.wc_feed_close_btn').click(function()
{
var days = 30;
var date = new Date();
date.setTime(date.getTime() + (days *24 *60 *60 *1000));
if(window.console)
console.log(date.toGMTString());
document.cookie = 'wc_feed_closed=true; expires=' + date.toGMTString() + ';';
jQuery('.live-sale-notify').css('display', 'none');
clearInterval(interval);
return false;
});
sales_feeds = jQuery('.live-sale-notify');
show_next_live_notify();
interval = setInterval(show_next_live_notify, (showtime + <?php print $s + 100; ?>));
});
</script>
Note: I want to delay the following execution.
function show_live_feed_notify(index)
{
sales_feeds.eq(index).animate({bottom: '10px'}, 1000);
current_index = index;
}
I tried inserting
var delay = 10000;
or
var interval = 10000;
none of them seem to work.
I also tried
setTimeout (function(); 3000);
it came out with uncaught syntax error.
Please Help me guys!
Note: I'm new to js/php coding...
Looking at your code, I think you should just remove the line
show_next_live_notify();
at the bottom of your script. It automatically executes everything right upon start instead of letting setInterval do its job
To delay the whole script, replace the last two lines in the jQuery call with something like this:
function startMe() {
interval = setInterval(show_next_live_notify, (showtime + <?php print $s + 100; ?>));
}
setTimeout(startMe, 10000);
You function name is show_live_feed_notify, and you tried to use setTimeout. Therefore I suggest you to try the following:
var delay = 10000; // 10 seconds
setTimeout(function() {
show_live_feed_notify(current_index + 1);
}, delay )

add cookie if no cookie of that name exists jquery

I have a splash page where the user chooses between 2 experiences. once chosen, a cookie is added so they will always get that experience (or at least for the next 30 days). however, if a user comes to the site directly to a sub-url and bypasses the splash page, they should be automatically added to the default experience and get the default cooke (theme1). everything except the default cookie part is working.
here's what i have:
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(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;
}
$('.theme2').click(function() {
createCookie('chooseTheme','chosenTheme2',30)
});
$('.theme1').click(function() {
createCookie('chooseTheme','chosenTheme1',30)
});
var x = readCookie('chooseTheme');
if ($.cookie('chooseTheme') === null) {
createCookie('chooseTheme','chosenTheme1',30);
}
if (x.indexOf('chosenTheme1') > -1) {
$('body').addClass('themeOne');
} else if (x.indexOf('chosenTheme2') > -1) {
$('body').addClass('themeTwo');
}
thanks!
Try running a loop that updates every 1 minute. During the update, it triggers the function that checks for the cookie like the following:
setInterval(checkCookie(), 60000);
//the 60000 is for 60000 milliseconds which is 1 minute.
function checkCookie() {
var x = readCookie('chooseTheme');
if ($.cookie('chooseTheme') === null) {
createCookie('chooseTheme','chosenTheme1',30);
}
if (x.indexOf('chosenTheme1') > -1) {
$('body').addClass('themeOne');
} else if (x.indexOf('chosenTheme2') > -1) {
$('body').addClass('themeTwo');
}
}
Then add the code above into your code and it will check for the theme every 1 minute. I hope this helps you.

Browser Bug showing time text on input

I am dealing with the following puzzle and I cannot understand why it is happening.
I have the following [I believe to be] equivalent pieces of javascript code, but one does not work as expected (notice the Console.Log):
Updates the UI a single time, then unexpectantly stops updating : http://jsfiddle.net/silentwarrior/1m0v6oj1/
jQuery(function () {
var isWorking = true;
if (isWorking) {
var timeEnd = 1431220406000; // generated from php
var timeNow = 1431210557000; // generated from php
var counter = 1;
var t = "";
setInterval(function () {
try {
var c = timeEnd - timeNow - counter;
console.log(c);
var d = new Date(c);
if (c <= 1) {
window.location.href = window.location.href;
return;
}
t = "";
if (d.getHours() > 0) {
t += d.getHours() + "h ";
}
if (d.getMinutes() > 0) {
t += d.getMinutes() + "m ";
}
t += d.getSeconds();
jQuery("#factory_start_prod").val("Working ... " + t + "s left");
counter = counter + 1;
} catch (e) {
}
}, 1000);
}
});
Updates the UI constantly as expected: http://jsfiddle.net/silentwarrior/n3gkum2e/
jQuery(function () {
var isWorking = true;
if (isWorking) {
var timeEnd = 1431220406000;
var timeNow = 1431210557000;
var counter = 1;
var t = "";
setInterval(function () {
try {
var c = timeEnd - Date.now();
console.log(c);
var d = new Date(c);
if (c <= 1) {
window.location.href = window.location.href;
return;
}
t = "";
if (d.getHours() > 0) {
t += d.getHours() + "h ";
}
if (d.getMinutes() > 0) {
t += d.getMinutes() + "m ";
}
t += d.getSeconds();
jQuery("#factory_start_prod").val("Working ... " + t + "s left");
counter = counter + 1;
} catch (e) {
}
}, 1000);
}
});
The only difference from each other is that, the one that works uses Date.now() to get the current timestamp, while the other one uses a pre-built time stamp.
Why would one example update the text in the input correctly while the other wouldn't?
PS: it is important to me to use generated timestamps instead of Date.now() in order to not depend on the users system when calculating the time left.
Your first example is working, however with each iteration you are only subtracting 1 from the timestamp value, which is equivalent to 1ms. Hence the value never appears to change unless you wait a really long time. You need to increment the counter by 1000 on each iteration for a second to be counted:
counter = counter + 1000;
Updated fiddle

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.

Categories