This is the code for countdown I am using . If the user reloads the page the countdown starts again .
I want the countdown to keep on running after the first time user has visited that page irrespective whether he closes the page or not . Please suggest a method . I think creating sessions might help but I have no idea about sessions .
<span id="countdown" class="timer"></span>
<script>
var seconds =120;
function secondPassed() {
var minutes = Math.round((seconds - 30)/60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
if (seconds == 0) {
clearInterval(countdownTimer);
document.getElementById('bonus').innerHTML = "Buzz Buzz";
} else {
seconds--;
}
}
var countdownTimer = setInterval('secondPassed()', 1000);
</script>
The question is not entirely complete. You want a counter for "forever" or for "a while after he accessed page first time".
For the first one, you need to count on the server side (you can for example create a db - or a file, or whatever you are comfortable with for saving things), and somehow identify the user, and get the first time he accessed. Then send back this info each time user logs, and count on client side in js, just like you do.
For the second one, you can either send a cookie with the timestamp he accessed first time, either save this info in session and use it each time user access the page.
Related
I'm writing a countdown timer using javascript in a php-mysql project, the countdown timer works correctly, but the problem is that when the user interacts with the game, the timer restarts. Should I do something with php sessions?
Any ideas?
<div>Time left = <span id="timer"></span></div>
<script>
document.getElementById('timer').innerHTML = 01 + ":" + 00;
startTimer();
function startTimer() {
var presentTime = document.getElementById('timer').innerHTML;
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if(s==59){m=m-1}
if(m<0){alert('You lose,click reset')}
document.getElementById('timer').innerHTML =m + ":" + s;
setTimeout(startTimer, 1000);
}
function checkSecond(sec) {
if (sec < 10 && sec >= 0) {sec = "0" + sec}; // add zero in front
of numbers < 10
if (sec < 0) {sec = "59"};
return sec;
}
</script>
Based on your comments to the main question, there are ways you can "jury rig" this, but I'm not entirely sure its the perfect solution for you.
When the user first initiates the game and you redirect them with a php action, I'm guessing this starts the initial timer, and subsequent interactions with the game also resets the timer also.
You could initiate a php session and save the start time of the game into a php session variable. Then when the page loads again, check for the existence of the session/variable, if it is set, then us it to do whatever you need it to as the difference between the current time and the start time of the game will tell you how long the game has been going for.
You can pass variables from php to JS with:
let js_start_time_variable = "<?=php_start_time_variable?>";
This solution is not pretty. I would recommend using something like vuejs to keep the entire game in a single page application without using page refreshes to php.
I have a code that needs to run a count-down timer, the counter needs to count down 15 min per user even if he\she leaves the page.
this is the cookie initialize line:
document.cookie = "name=timerCookie; timeLeft=" + initialTime + "; expires=" + expires;
and this is how I update the cookie:
document.cookie = "name=timerCookie; timeLeft=" + timeLeft + "; expires=" + expires;
when I try to read the cookie I get "name=timerCookie"
am I setting the cookie correctly?
can I use cookie this way?
EDIT****:
apparently, cookie can contain only 1 segment(aka timeLeft) by removing the name value the issue was solved.
Well, I came up with this solution while I was offline and before I learned what your use case actually is.
I was thinking it would be better to use localStorage since MDN says:
"Cookies were once used for general client-side storage. While this was
legitimate when they were the only way to store data on the client, it
is recommended nowadays to prefer modern storage APIs."
Since your server needs to know about the user's "time remaining", you probably want cookies after all (unless you can just have the browser update the server at unload time), but maybe you can adapt this idea to your purpose.
I was also thinking that "even if he/she leaves the page" meant that the timer should keep ticking while they're away -- but this part should be relatively easy to fix.
I'm including this as HTML (to copy/paste) because SO snippets are sandboxed and won't run code that uses localStorage.
<!DOCTYPE html><html><head></head><body>
<p id="display">__:__</p>
<script>
let expires = localStorage.getItem("expires"); // Gets the stored expiration time
const display = document.querySelector("#display"); // Identifies our HTML element
// Makes a helper function to treat dates as accumulated seconds
const getSecondsSinceEpoch = ((date) => Math.floor(date.getTime()/1000));
// Sets the expiration time if countdown is not already running
if(!expires){
expires = getSecondsSinceEpoch(new Date()) + (60 * 15); // 15 minutes from now
localStorage.setItem("expires", expires);
}
// Calculates how long until expiration
let pageLoadedAt = getSecondsSinceEpoch(new Date());
let secondsRemaining = parseInt(expires) - pageLoadedAt;
// Starts the countdown (which repeats once per second)
setInterval(countdown, 1000);
function countdown(){
// When time expires, stops counting and clears storage for the user's next visit
if(secondsRemaining === 0){
clearInterval();
localStorage.clear(); // You don't want this here -- it resets the clock
}
else{
// Until time expires, updates the display with reduced time each second
display.textContent = formatTime(--secondsRemaining);
}
}
function formatTime(time){
let mins = Math.floor(time/60).toString();
let secs = Math.floor(time%60).toString();
secs = secs.length == 2 ? secs : "0" + secs; // Ensures two-digit seconds
return `${mins}:${secs}`
}
</script>
</body></html>
I have a URL that is being invoked by a cron job, but I am not getting it to work.
I am planning to do the same using Javascript: how can I reload the page this way on particular hour of the day (8:00 PM)?
I wanted to reload a controller from the index page. I will write this script and place the URL in here – Hasif
Since the use of Javascript in your situation is restricted to the front-end, the user would need to keep the page open (index as you mentioned) the whole time. This means that:
the URL call will only be made if the user keeps the browser open (if this task really needs to run everyday, you should not rely on the client side to make it happen);
the cron-job you mentioned is the better alternative, but you have no way to force the user's browser to open up at 8:00 PM everyday;
the user's local time will not be useful to trigger this event if the URL is supposed to be loaded for all users at the same time, so trigger it at a certain time in the UTC timezone (for example).
Solution
Create a cookie that stores the date and time when the index page was last loaded by the user and each time the page loads, compare it to the current date and load the URL only once (MDN example). You might want to set the cookie in the backend, but a simple example to store and load it in JS:
var td =new Date(), date2store = `${td.getUTCFullYear()}-${td.getUTCMonth().toString().padStart(2,0)}-${td.getUTCDate().toString().padStart(2,0)} ${td.getUTCHours().toString().padStart(2,0)}:${td.getUTCMinutes().toString().padStart(2,0)}`;
alert('Cookie to store: last_date=' + date2store + ' --> Is it after 8 PM UTC? ' + (new Date(date2store).getUTCHours() >= 19 ? 'YES!' : 'NO!' ));
If the user keeps the browser open until the next day use a simple script loaded into the page to check the current UTC hour and update:
// place the code below in a setInterval(function() {...}, 1000*60*60);
// the if below should also the test the current cookie's datetime as the first condition
// 0 index hour exists (therefore compare with 19 instead of 20)
if(new Date().getUTCHours() >= 19) {
alert('Past 8 PM');
// save the current date and time in the cookie HERE
// reload the index page
// window.location.reload(true); // true for not using cache
// OR redirect to a new location
// window.location.href = 'https://...';
} else alert('Not 8 PM yet');
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
I have designed counter as follows.
I got the timer seconds from the server. And converted to hours, minutes, seconds.
timerInterval = setInterval(
function()
{
if(hours.toString().length == 1){hours = "0"+hours;}
if(minutes.toString().length == 1){minutes = "0"+minutes;}
if(seconds.toString().length == 1){seconds = "0"+seconds;}
if(seconds > 0){
seconds--;
if(seconds.toString().length == 1){seconds = "0"+seconds;}
}
else if(seconds == 0 && (minutes > 0)){
minutes = minutes - 1;
seconds = 59;
}
else if(minutes == 0 && (hours > 0)){
hours = hours - 1;
minutes = 59;
}
if(hours == 0 && minutes ==0 && seconds ==0){
clearInterval(timerInterval);
localStorage.removeItem("endTime");
$(".submitTest").click();
}
$("#timer").html(hours+":"+minutes+":"+seconds);
localStorage['endTime'] = (hours*3600+minutes*60+seconds);
},1000);
It displays the timer.
Problem with this
User can edit the timer and cheat.
Solutions I found
1) Store the timer last time in the server side. When user submits, we can calculate submission time against the time stored in the server.
**Problem**: If I send submission time, user can edit it. So no use of storing
it in the server.
2) I can just send the data to the server when timer expires or user submits.
And I check the current time against the store time in the server.
Problem: Stored time in the server: 10:25PM.
Server sends data to the client with duration of 25minutes at the time of 10:00pm.
There must be a delay in the data reaches the client. For example, it reaches 10:00 05seconds. And user submits exactly after 25 minutes [means timer expires]. And there must be a delay in the data which reaches the server. So it reaches at 10:25 20s[05+15seconds delay]. I stored the end time in the server as 10:25pm. So 20 seconds delay would fail as user cheated.
Solution is to have a +/- time. For example I would allow 10:27pm as valid time[2min extra]
But How does this 2min would be a valid one?
3) Server Sent Events
I faced the same issue as second one.
But here solution is different: If timer expires on the server side, collect data from the user without waiting for his submission and do the submission action on the server side. But still user can stop JS which sends data to the server.
How do I solve this timer issues? Any suggestions?
I suggest to store in session when the user require the page and also send to the page the time stored in session and keep the timer running in the front-end. When user do the submit you check on server-side the time stored in session and the time submitted, of course there will be a little difference of seconds or milliseconds. So you can define a margin to consider as a fraud.
I am developing a website that has two back to back web broadcasts. I have used PHP to display the time that the buttons should be enabled and disabled. Now I need to use Javascript to automatically refresh the page before the first broadcast, before the second broadcast and after the second broadcast. I implemented the following script and it does refresh the page at the given time, however, it doesn't work exactly as I need it to. I need to alter the script so that it refreshes the page on Sundays at 7:45pm, 8pm and 8:30pm EST only.
I'm using a modified script from this answered question
function refreshAt(hours, minutes, seconds) {
var now = new Date();
var then = new Date();
if(now.getUTCHours() > hours ||
(now.getUTCHours() == hours && now.getUTCMinutes() > minutes) ||
now.getUTCHours() == hours && now.getUTCMinutes() == minutes && now.getUTCSeconds() >= seconds) {
then.setUTCDate(now.getUTCDate() + 1);
}
then.setUTCHours(hours);
then.setUTCMinutes(minutes);
then.setUTCSeconds(seconds);
var timeout = (then.getTime() - now.getTime());
setTimeout(function() { window.location.reload(true); }, timeout);
}
Then I call the refreshAt() function.
refreshAt(19,45,0); //Will refresh the page at 7:45pm
refreshAt(20,00,0); //Will refresh the page at 8:00pm
refreshAt(20,30,0); //Will refresh the page at 8:30pm
Where I get confused is how to alter this script to only implement the refresh for EST on Sundays.
I figured it out. Here's the script:
function refreshAt(hours, minutes, seconds, day) {
var now = new Date();
var then = new Date();
var dayUTC = new Date();
if(dayUTC.getUTCDay() == day) {
if(now.getUTCHours() > hours ||
(now.getUTCHours() == hours && now.getUTCMinutes() > minutes) ||
now.getUTCHours() == hours && now.getUTCMinutes() == minutes && now.getUTCSeconds() >= seconds) {
then.setUTCDate(now.getUTCDate() + 1);
}
then.setUTCHours(hours);
then.setUTCMinutes(minutes);
then.setUTCSeconds(seconds);
var timeout = (then.getTime() - now.getTime());
setTimeout(function() { window.location.reload(true); }, timeout);
}
}
And then I just call the refreshAt() function:
refreshAt(20,00,0,1); //Will refresh the page at 8:00pm on Monday UTC or 3:00pm EST
An alternative approach would be to use Pusher. This keeps an open connection to receiving events.
Include the Pusher javascript:
<script src="http://js.pusher.com/1.11/pusher.min.js"></script>
Bind to a pusher event of "refresh" with this code:
var pusher = new Pusher('abc123'); // Get a key when you sign up and replace this
var refreshChannel = pusher.subscribe('refreshing');
refreshChannel.bind('refresh', function(thing) {
location.reload(true);
});
Then at 8pm (or whenever you want) manually issue a pusher event on the Pusher control panel page, and all of the people currently viewing the page would be reloaded.
You can add the test even for the day of the week, for example :
now.getDay() == "Sunday"
function refreshAt(day, hours, minutes, seconds)
{
Date.getDay() = day
...
}
0 is Sunday, 6 is Saturday.
I had the same problem as you. I'm building a site that sounds a lot like yours, also using PHP to enable and disable page elements before and after the broadcast time. Your solution seemed promising, but ultimately I was dissatisfied using pure Javascript for the page reload. Javascript gets its time from the client's machine, whereas PHP gets it from the server, and even a small difference between the two could wreck the whole system. (i.e. the page could refresh 30 seconds before the PHP enabled the buttons, causing some viewers to assume the whole thing is down.)
I solved the problem by using PHP to tell the Javascript function what time it is, and it works like a charm. The only issue is that it runs every day, instead of just on one day of the week, but that doesn't bother me- users will have no reason to be viewing the page other than the broadcast day.
This is all you need- I put this right after the <body> tag:
<script type="text/javascript">
setTimeout(function() { window.location.reload(true); }, 1000*<?php
$then = mktime(15,00,0);
$tomorrow = mktime(15, 00, 0, date("m") , date("d")+1);
$now = time();
if ($now > $then) {echo $tomorrow - $now;}
else {echo $then - $now;}?>); </script>