javascript countdown synchronize on different browsers - javascript

I'm sorry if this question is a bit tricky but I have no other way of asking it and I am an absolute noob in javascript world.
I have this javascript counter that someone helped me to gather on stackoverflow and it works fine BUT
the countdown timer will start from the beginning on a different browsers.
i.e. when I look at it on Firefox, it will carry on counting down and it will keep working as it should. lets say the timer is set to countdown a day. on Firefox it will show 23:24 hours/minutes left but if I open a new browser (any browser), it will show the timer 23:59 hours/minutes left and it will start counting down from there... even though the countdown timer was already running on the same page!!
here is the code:
<script type="text/javascript">
var EXPIRY = parseInt(new Date().getTime()/1000) + 24*60*60;
var counter = null;
var counter_interval = null;
function setCookie(name,value,days) {
console.log("setting "+name+" "+value);
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() {
EXPIRY = parseInt(new Date().getTime()/1000) + 24*60*60;
}
function stopCounter() {
window.clearInterval(counter_interval);
deleteCookie('Expiry');
}
function updateCounter() {
var msg = '';
curTime = parseInt(new Date().getTime()/1000);
if (curTime < EXPIRY) {
msg = convertSecondsToDays(EXPIRY - curTime);
}
else {
EXPIRY = parseInt(new Date().getTime()/1000) + 24*60*60;
}
var el = document.getElementById('counter');
if (el) {
el.innerHTML = msg
}
}
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 +":" + hours +":"+mins + ":"+ secs + "";
}
function startCounter() {
stopCounter();
setCookie('Expiry', EXPIRY, 1);
counter_interval = window.setInterval(updateCounter, 1000);
}
function init() {
EXPIRY = getCookie('Expiry');
if (!EXPIRY) {
console.log("unable to find cookie");
resetCounter();
}
startCounter();
}
init();
</script>
you can view it on the fiddle here: http://jsfiddle.net/h2DEr/1/
how can i make it in a way that it will show the same time left on all the browsers as it will be displayed on the same page?
Thanks
Edit:
I found this code which works with mysql. it works fine but instead of counting down it will show how many days/hours/minutes the product/item was posted on the site. and this doesn't need any javascript as is...
This is sort of what I am looking for but instead of counting up it needs to countdown:
<?php
//list fields and convert to seconds
$countdown['days']=(5) * 24 * 60 * 60;
$countdown['hours']=(3) * 60 * 60;
// etc, etc
$countsum=time() + $countdown['days'] + $countdown['hours']; //and so on
// the above would be the timestamp to enter into the table
##########
// 'dumbed down' query
include "config/connect_to_mysql.php";
$result=mysql_query("SELECT * FROM tomProduct WHERE id='id';");
while ($row=mysql_fetch_assoc($result))
$time=$row['date_added'] - time(); //this field would be a PHP timestamp (time())
$count=getdate($time);
$x=getdate(); //todays information
$count['mday'] -= $x['mday'];
$count['hour'] -= $x['mday'];
$count['minutes'] -= $x['minutes'];
echo "$count[mday] Days $count[hour] Hours $count[minutes] Minutes"; //etc
// untested, but should work
?>

JavaScript is always running on the client. One instance of the timer has no knowledge of any other instance running elsewhere.
To synchronize time between different browsers, you would need server-side scripts.
Using expiration-time-stamps in a server-side script in conjunction with JavaScript timers should give you the synchronization you are looking for.

Cookies are not transferred from browser to browser. They are stored in the web browser.

Related

Session timeout counter

I'm trying to write a session timeout counter, so that after 15 minutes of inactivity the customer basket is deleted, the code I have so far half works but I cannot work out how to create the counter to keep track of the time. I have set the time to a low number to test
$(document).ready(function() {
var sessionTimeoutWarning =1;
var sessionTimeout = 3;
var sTimeout = parseInt(sessionTimeoutWarning) * 60 * 1000;
var timeOnPageLoad = new Date();
setTimeout(sessionWarning(), sTimeout);
function sessionWarning() {
var minutesForExpiry = (parseInt(sessionTimeout) - parseInt(sessionTimeoutWarning));
var message = "Your session will expire in another " + minutesForExpiry + " mins! Please continue browsing before your basket is deleted.";
alert(message);
var currentTime = new Date();
var timeForExpiry = timeOnPageLoad.setMinutes(timeOnPageLoad.getMinutes() + parseInt(sessionTimeout));
if (Date.parse(currentTime) > timeForExpiry) {
alert("Session expired. Items in the basket will be deleted.");
window.location = "/";
}
}
});
Any help would be appreciated

Can't reset a JS timer in a one state app (ajax page loads)

I am having an issue with reseting a JS timer in a one state app that uses ajax to load new pages, so the page rarely experiences a full reload. The timer is used to countdown the date on inquiry pages (similar concept to ebay) and there are multiple inquiry pages - all with different timers and expiry dates.
The timer works perfectly on a full page reload, but after that, it gets increasingly faster and starts storing all the different timers simultaneously (e.g. if I visited three inquiry pages and initialized three timers, now its gonna count 3 seconds per second instead of 1.)
Here is my timer function
var timer = {
isActive : null,
firstLoad : null,
currentTime: null,
distance : null,
duration : null,
init: function() {
var scope = timer;
if (scope.isActive) {
scope.counter();
}
else {
$("#countdown").html("-");
}
},
counter: function() {
var scope = timer;
scope.countdown = setInterval(function() {
if (scope.firstLoad) {
scope.distance = scope.activeTo - scope.currentTime;
scope.duration = moment.duration(scope.distance);
scope.firstLoad = false;
}
else {
scope.duration.subtract(1, "second");
}
// Time calculations for days, hours, minutes and seconds
var days = scope.duration.days();
var hours = scope.duration.hours();
if (hours < 10) {
hours = "0" + hours;
}
var minutes = scope.duration.minutes();
if (minutes < 10) {
minutes = "0" + minutes;
}
var seconds = scope.duration.seconds();
if (seconds < 10) {
seconds = "0" + seconds;
}
// Display the result in the element with id="countdown"
jQuery("#countdown").html(days + " <%= pdo.translate("countdown.days.label")%> " + hours + ":" + minutes + ":" + seconds);
// If the count down is finished, write some text
if (scope.distance < 0) {
$("#addNewBid, #cancelInquiry, #editInquiry").hide();
$("#countdown").html("<%= pdo.translate("countdown.timeend.label")%>");
}
}, 1000);
},
reset: function() {
var scope = timer;
clearInterval(scope.countdown);
scope.isActive = null;
scope.firstLoad = null;
scope.currentTime = null;
scope.distance = null;
scope.duration = null;
}
};
And this is how I reset and initialize it on new page load.
$(document).ready(function ($) {
timer.reset();
timer.currentTime = new moment("<%=pdo.getTime()%>");
timer.activeTo = new moment("<%= pdo.getInquiry().getActiveTo() %>");
timer.isActive = <%=pdo.getInquiry().isActive()%>;
timer.firstLoad = true;
timer.init();
});

Show Div After 30 Sec

I'm trying to make a welcome message for the user.
My planning is:
if the user visits the first time the page then show a div message after 30 sec.;
if the user already visited the page there is no need to show div message.
I have writed this code:
My cookies code
<script type="text/javascript">
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;
}
function eraseCookie(name) {
createCookie(name, "", -1);
}
</script>
My display code
<script type="text/javascript">
function showbox() {
document.getElementById("apDiv1").style.visibility = "visible";
}
setTimeout("showbox()", 30000); // after 5 secs
</script>
<script type="text/javascript">
if (!readCookie('visitedPreviously')) {
showbox();
//document.write(' Your Message Goes Here And You See It Only Once ');
createCookie('visitedPreviously', 'visitedPreviously', 3); // 365 days persistence
}
//eraseCookie('visitedPreviously'); // FOR TEST PURPOSES
</script>
My problem is when a visitor visits the page first time, the div shows immediately (30 sec.) - Doesn't work
But when a returning visitor visits again the page the div shows after 30 sec.
I want for a first time user visit to show a div message after 30 sec.
Please help me.
According to your explanation you want to show a dialog after 30 seconds only to new user. So you need to change your code into below:
<script type="text/javascript">
function showbox() {
document.getElementById("apDiv1").style.visibility = "visible";
}
if (!readCookie('visitedPreviously')) { //if he/she is a new user
setTimeout("showbox()", 30000); // after 30 secs
//document.write(' Your Message Goes Here And You See It Only Once ');
createCookie('visitedPreviously', 'visitedPreviously', 3); // 365 days persistence
}
//eraseCookie('visitedPreviously'); // FOR TEST PURPOSES
</script>
You need to remove quotes around showbox.
This the syntax of the setTimeout fnction,
setTimeout(function,milliseconds,param1,param2,...)
setTimeout expects the first parameter to be a function call.
function showbox() {
document.getElementById("apDiv1").style.visibility = "visible";
alert();
}
setTimeout(showbox, 30000); // after 5 secs
if (!readCookie('visitedPreviously')) {
//I added a set timeout here which is what you need
setTimeout(showbox, 30000); // after 5 secs
//document.write(' Your Message Goes Here And You See It Only Once ');
createCookie('visitedPreviously', 'visitedPreviously', 3); // 365 days persistence
}
//eraseCookie('visitedPreviously'); // FOR TEST PURPOSES
Remove the quote and the brackets in the "showbox()". Like this:
setTimeout(showbox, 30000);
I've corrected your code below, you had the setTimeout being called before the cookie had been checked!
function showbox() {
document.getElementById("apDiv1").style.visibility = "visible";
}
if (!readCookie('visitedPreviously')) {
setTimeout("showbox()", 30000); // after 30 seconds
//document.write(' Your Message Goes Here And You See It Only Once ');
createCookie('visitedPreviously', 'visitedPreviously', 3); // 365 days persistence
}
Please try it out.
You don't need quotes around showbox:
setTimeout(showbox, 30000);
Docs: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
You should modify your display code to:
<script type="text/javascript">
function showbox() {
document.getElementById("apDiv1").style.visibility = "visible";
}
setTimeout(showbox, 30000); // after 5 secs
</script>
<script type="text/javascript">
if (!readCookie('visitedPreviously')) {
//I added a set timeout here which is what you need
setTimeout(showbox, 30000); // after 5 secs
//document.write(' Your Message Goes Here And You See It Only Once ');
createCookie('visitedPreviously', 'visitedPreviously', 3); // 365 days persistence
}
//eraseCookie('visitedPreviously'); // FOR TEST PURPOSES
</script>
Please note the change is made above is:
//I added a set timeout here which is what you need
setTimeout(showbox, 30000); // after 5 secs
It is not a good practice to send a function as a string as you have done in the set timeout.
You need to modify your code to this
<script type="text/javascript">
function showbox() {
if (!readCookie('visitedPreviously')) {
document.getElementById("apDiv1").style.visibility = "visible";
//document.write(' Your Message Goes Here And You See It Only Once ');
createCookie('visitedPreviously', 'visitedPreviously', 3); // 365 days
}
//eraseCookie('visitedPreviously'); // FOR TEST PURPOSES
}
setTimeout(showbox, 30000); // after 5 secs
</script>

Stop watch java script without using Date.getTime()

As a java script beginner, I wanted to try my hand at writing stop watch code and I wrote the following:
<!DOCTYPE html>
<html>
<body>
<p>A script on this page starts a stopwatch:</p>
<p id="demo"></p>
<button id="start-stop" onclick="myTimerFunction()">Start time</button>
<button id="resetter" style="visibility:hidden" onclick="resetTimer()">Reset</button>
<script>
var timer = new Object();
timer.hours = 0;
timer.minutes = 0;
timer.seconds = 0;
timer.milliseconds = 0;
timer.add = add;
function add() {
timer.milliseconds+=10;
if(timer.milliseconds == 1000) {
timer.seconds++;
timer.milliseconds = 0;
}
if(timer.seconds == 60) {
timer.minutes++;
timer.seconds = 0;
}
if(timer.minutes == 60) {
timer.hours++;
timer.minutes = 0;
}
}
timer.display = display;
function display () {
var str = "";
if(timer.hours<10) {
str += "0";
}
str += timer.hours;
str += ":";
if(timer.minutes<10) {
str += "0";
}
str += timer.minutes;
str += ":";
if(timer.seconds<10) {
str += "0";
}
str += timer.seconds;
str += ":";
/*var x = timer.milliseconds/10;
if(x < 10) {
str += "0";
}*/
if(timer.milliseconds<10) {
str += "0";
}
if(timer.milliseconds<100) {
str += "0";
}
str += timer.milliseconds;
return str;
}
timer.reset = reset;
function reset() {
timer.hours = 0;
timer.minutes = 0;
timer.seconds = 0;
timer.milliseconds = 0;
}
var myVar;
function start() {
timer.add();
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = timer.display() + "\t" + t;
}
function stop() {
clearInterval(myVar);
}
function resetTimer() {
stop();
timer.reset();
document.getElementById("demo").innerHTML = timer.display();
document.getElementById("start-stop").innerHTML="Start time";
document.getElementById("resetter").style.visibility="hidden";
}
function myTimerFunction() {
var x = document.getElementById("start-stop");
if(x.innerHTML.match("Start time")) {
document.getElementById("resetter").style.visibility="visible";
myVar = setInterval(function(){start()},10);
x.innerHTML="Stop time";
}
else if(x.innerHTML.match("Stop time")) {
stop();
x.innerHTML="Start time";
}
}
</script>
</body>
</html>
But, the problem is when I put the delay in setInterval(func,delay) as 1 and doing corresponding changes, it is not giving reliable timing for seconds. It is slower than a normal clock. It gives 'kind of' reliable timing for delay >= 10.
I checked for stop watch js scripts online but all of them use some or other form of Date() and set "delay" as "50", which I do not understand why, as of now. There is an answer here in SO which doesn't use Date() but it also has the same problem as mine. I could not comment there as I do not have enough reputation so I am asking a question instead.
So, my question is: Is it impossible to achive normal clock reliability, if we don't use Date() function? Else if it is possible, please help me improve this piece of code or please provide some pointers.
Thanks.
Here's how you'd do it without getTime, which you really shouldn't...
var ms = 0;
var intervalID;
function start() {
var freq = 10; // ms
intervalID = setInterval(function () {
ms += 10;
var myDate = new Date(ms);
document.getElementById('watch').innerHTML = myDate.getUTCHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds() +
":" + myDate.getMilliseconds();
}, freq);
}
function stop() {
clearInterval(intervalID);
}
function reset() {
ms = 0;
myDate = new Date(ms);
document.getElementById('watch').innerHTML = myDate.getUTCHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds() +
":" + myDate.getMilliseconds();
}
Fiddle
As you've found out setInterval/setTimeout is not reliable. You must use a native time library to get a reliable time.
Since you can't keep the time in JavaScript the idea is that you poll the time, and poll it often so that it looks close enough.
If you naively do:
setInterval(function () {
console.log((new Date()).getTime();
}, 1000); // 1 second
you will see that it will skip seconds.
A better approach is something like:
var last = 0;
setInterval(function () {
var now = Math.floor((new Date()).getTime() / 1000); // now in seconds
if (now !== last) {
console.log(now);
last = now;
}
}, 10); // 10ms
If you want more information as too why JavaScript timers are unreliable, read this great article.
http://ejohn.org/blog/how-javascript-timers-work/

Running a real-time clock with AJAX

Now that I was helped getting AJAX running just great, I'm having problems running a clock function with it....
Clock code (located in the head):
<script type="text/javascript">
var ampm = "AM"; //Default
var message="";
function startTime()
{
var today = new Date(); //Number goes here
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);
h=checkTime2(h);
document.getElementById('clocktxt').innerHTML=h+":"+m+":"+s+ " " +ampm + " " + message;
//t=setTimeout('startTime()',500);
}
function checkTime(i)
{
if (i<10)
{
i="0" + i;
message = "How long you gonna sit there?";
}
return i;
}
function checkTime2(i)
{
if (i>12)
{
i=i-12;
ampm="PM";
}
return i;
}
//setInterval(startTime,1000);
</script>
AJAX code (bottom of the document):
<script type='text/javascript'>
function CheckForChange(){
//alert("<?echo (count($listArray)) . ' and ' . count(file($filename_noformat))?>");
//if (<?echo count($listArray)?> == <?echo count(explode("\n", $filename_noformat))?>){
//setInterval("alert('Yup, it is 1')", 5000);
//alert('Now it is changed');
//}
var ajaxReady = new XMLHttpRequest();
ajaxReady.onreadystatechange = function(){
if (ajaxReady.readyState == 4){
//Get the data
//document.getElementById('clocktxt').innerHTML = ajaxReady.responseText;
//startTime();
//alert("here");
//alert(ajaxReady.responseText);
}
}
ajaxReady.open("GET","ServerTime.php",true);
ajaxReady.send(null);
}
setInterval(CheckForChange(), 1000);
setInterval(startTime(),1000);
</script>
What I'm trying to do is pass the input from ServerTime.php which is just a count of milliseconds from Unix epoch, into the clock, so the clock is being updated by the AJAX every second and the clock function runs with a new starting value each second.... I used to have parameters for the clock function before I realized the clock wasn't even getting called.
What do you think is wrong? I'm guessing it has something to do with the clock and the caller of the clock being in two different script tags, but I can't think of how to get around it. For some reason when I moved the AJAX part into the same script tag, following the clock, nothing happens.
To Kolink: I have this
function getTheNow(){
TIMESTAMP = <?php echo time(); ?>000;
offset = new Date().getTime()-TIMESTAMP;
setInterval(function() {
var now = new Date();
now.setTime(now.getTime()-offset);
// print out the time according to the variable `now`
//alert(now);
},5000);
return now;
}
function startTime()
{
var now = getTheNow;
//alert(now);
var today = new Date(); //Number goes here
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);
h=checkTime2(h);
document.getElementById('clocktxt').innerHTML=h+":"+m+":"+s+ " " +ampm + " " + message;
t=setTimeout('startTime()',500);
}
function checkTime(i)
{
if (i<10)
{
i="0" + i;
message = "How long you gonna sit there?";
}
return i;
}
function checkTime2(i)
{
if (i>12)
{
i=i-12;
ampm="PM";
}
return i;
}
setInterval(startTime,1000);
Computer clocks are not so inaccurate that you have to re-sync them every second. Try every ten minutes, or even every hour.
In fact, I just do away with synchronising altogether. It is far easier to do this:
<script type="text/javascript">
TIMESTAMP = <?php echo time(); ?>000;
offset = new Date().getTime()-TIMESTAMP;
setInterval(function() {
var now = new Date();
now.setTime(now.getTime()-offset);
// print out the time according to the variable `now`
},1000);
</script>
JavaScript 101 error
setInterval(CheckForChange(), 1000);
setInterval(startTime(),1000);
You are not assigning the function, you are calling/executing them and saying what ever is returned from these functions should be set. Drop the () so you are referencing the functions.
setInterval(CheckForChange, 1000);
setInterval(startTime,1000);

Categories

Resources