I'm trying to make this count down not reset on load or refresh. Can anyone help me with this? I have heard I can use local storage but surly I will need to change this code to be server sided with PHP and MySQL. If you do have any resources which show you the PHP version could you send them to me or post as an answer?
var updateTimer = function() {
timer = localStorage.getItem('timer') || 0;
if ( timer === 0 ) {
$("div#timer").html("Timer is unset");
} else {
timer--;
localStorage.setItem('timer', timer);
$("div#timer").html(timer);
}
};
$(function() {
setInterval(updateTimer, 1000);
$("#start").click( function() {
localStorage.setItem('timer', 500);
});
});
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000);
initializeClock('clockdiv', deadline);
Thank you
If you want to completely avoid server sided coding, you can save values using Cookies.
In javascript this is easily done by document.cookie = "yourValues, expiryDate".
JQuery also has some nice functions to handle cookies.
You may want to adjust your script to calculate the passed time between loads or not having the clock run, but that is optional.
http://www.w3schools.com/js/js_cookies.asp <- Here is a simple tutorial on how to use them.
With php you can use the cookie's to achieve the same.
setcookie($timer); // Set timer
$_COOKIE['timer']; // Get timer
You can start inserting into mysql in every refresh but use $_COOKIE to show. Mysql is just for tracking and getting correct time after refresh the page.
mysql_query("UPDATE table SET timer = '$timer'"); // Inserting every refresh
So when page loads either get form stored cookie or retrieve from mysql table
But COOKIES will be faster than using only mysql method(It won't work properly as it need to request every second)
Related
I am trying to create a countdown website which runs a set of schedules as countdowns one after another. Each schedule is an array of a pair of strings which represent the start time and end time of each schedule.
Expected Behaviour:
I want the second schedule to start when the first one ends.
Current Behaviour:
After the first schedule is completed, the date shown on the webpage shows NaN for all the values.
Please help me understand what I am doing wrong as I am new to programming.
Codepen of Minimum Complete Verifiable Example [You may have to change the start time and end times of the schedules to be in the future depending on when you open it to reproduce the issue]
Code Sample:
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
clock.style.display = 'block';
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
// var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000);
initializeClock('clockdiv', schedule);
var schedule = [
['2018-05-01', '2018-05-02 13:36:00'],
['2018-05-02 13:36:01', '2018-05-09']
];
// iterate over each element in the schedule
for(var i=0; i<schedule.length; i++){
var startDate = schedule[i][0];
var endDate = schedule[i][1];
// put dates in milliseconds for easy comparisons
var startMs = Date.parse(startDate);
var endMs = Date.parse(endDate);
var currentMs = Date.parse(new Date());
// if current date is between start and end dates, display clock
if(endMs > currentMs && currentMs >= startMs ){
initializeClock('clockdiv', endDate);
}
}
The problem I think is mainly in two areas:
The for loop runs only once so the second schedule is never started after the first one ends (the for loop would have obviously finished executing and does not startup again). That loop should ideally run again once the first schedule ends.
The function to clear the timeout should be moved before the DOM update as the function getTimeRemaining may return inconsistent values when the schedule is over.
Solutions:
Wrap the schedule start code in a function startNewScheduleIfNeeded and run that new function each time a schedule ends and we clear the timer
Move the check to see if we should clear the timer above the DOM update in updateClock to avoid NaN values
Sample Code:
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
total: t,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
clock.style.display = "block";
var daysSpan = clock.querySelector(".days");
var hoursSpan = clock.querySelector(".hours");
var minutesSpan = clock.querySelector(".minutes");
var secondsSpan = clock.querySelector(".seconds");
function updateClock() {
var t = getTimeRemaining(endtime);
// Solution Part 2: Move check before DOM update and return early if needed
if (t.total <= 0) {
clearInterval(timeinterval);
// Schedule has ended, run function to start another if needed.
startNewScheduleIfNeeded();
return;
}
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ("0" + t.hours).slice(-2);
minutesSpan.innerHTML = ("0" + t.minutes).slice(-2);
secondsSpan.innerHTML = ("0" + t.seconds).slice(-2);
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
// var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000);
//initializeClock('clockdiv', schedule);
// Solution Part 1: Wrap schedule start in a function to resuse when schedules end
function startNewScheduleIfNeeded() {
var schedule = [
["2018-05-03", "2018-05-03 11:17:00"],
["2018-05-03 11:17:00", "2018-05-09"]
];
// iterate over each element in the schedule
for (var i = 0; i < schedule.length; i++) {
var startDate = schedule[i][0];
var endDate = schedule[i][1];
// put dates in milliseconds for easy comparisons
var startMs = Date.parse(startDate);
var endMs = Date.parse(endDate);
var currentMs = Date.parse(new Date());
// if current date is between start and end dates, display clock
if (endMs > currentMs && currentMs >= startMs) {
initializeClock("clockdiv", endDate);
}
}
}
startNewScheduleIfNeeded();
Other observations:
there was a random call to initializeClock which I have commented out
You only need to use Date.parse if your input is a string (like your schedule list). calling Date.parse(new Date()) is redundant. You can just use new Date(). Also, Date.parse DOES NOT return an integer (milliseconds). It returns a Date object which gets casted to a number when you do comparison like <
The end time of one schedule must be equal to the start time in the next schedule for this method to work. If you have gaps (even one second) the function to start the schedule will execute before the check to see if the current time is between the start time and end time can pass. (in the example in your question, end time of first schedule is '2018-05-02 13:36:00' and the start time for the next one is '2018-05-02 13:36:01'. This won't work - the start time of the second schedule has to be '2018-05-02 13:36:00').
I am using this timer on each of my product pages: http://www.screencast.com/t/hsmzVOLBUJ
and example of product page URL:
https://www.tresor-ethnique.com/collections/celtique/products/pendentif-chene-millenaire
It starts at 12hrs 4mn 26s and then decreases.
I would like it to be set with a cookie so that when the user navigates between different product pages, it keeps decreasing from the value of other pages ; and also if the user comes back in 12hrs, it displays 0hrs 4mn 26s.
So I am a bit unfamiliar with the integration of cookie in javascript, this would appear in the end of my code there:
document.cookie = 'myClock='
So far, the timer resets after each refresh
Do you have any idea to prevent that?
This would be a great help, thank you very much :)
<div id="clockdiv">
<span class="days"></span><div class="smalltext">jours</div>
<span class="hours"></span><div class="smalltext">hrs</div>
<span class="minutes"></span><div class="smalltext">mins</div>
<span class="seconds"></span><div class="smalltext">secs</div>
</div>
<script type="text/javascript">
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var currentTime = Date.parse(new Date());
if(document.cookie && document.cookie.match('myClock')){
var deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
}
else{
var timeInHours = 12;
var timeInMinutes = 4;
var timeInSeconds = 26;
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInHours*60*60*1000 + timeInMinutes*60*1000 + timeInSeconds*1000);
document.cookie = 'myClock=' + deadline + '; path=/; domain= .https://www.tresor-ethnique.com/';
initializeClock('clockdiv', deadline);
}
</script>
I have a simple JS code to do countdown on the Client browser but there is a short coming the timer depends on the client machine so i want to get the Current Time and elapsed time from the Server.
Below is my working but it doesn't work.
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(current_time);
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime, current_time) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime, current_time);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
$('#clockdiv').html('You can\'t Reserve anymore')
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var deadline = '2017-02-24 18:12:29';
var current_time = new EventSource('Server/script/example.php');
current_time.onopen = function(event) {
//console.log(event)
current_time.onmessage = function(event)
{
return event.data;
}
current_time.onerror = function (error) {
//console.log('we have an error')
}
}
console.log(current_time)
initializeClock('clockdiv', deadline, current_time);
So am trying to use HTML SSE server Sent Event so as Listen to response instead of making the request.
current_time variable is empty and the output of the Time is NAN NAN NAN
So is there a better of achieving the above or can some work this code for me.
I'm trying to create a countdown counter that should countdown for 24 hours, displaying the days, the hours, the minutes and the seconds. The question is that I want to make it somehow save the progress. For example, I put the countdown to start from now till tomorrow the same time (24 hours) and when a user comes in my site after 2 hours the counter should start from 22 hours for that user and if the user closes the site and then comes back after 2 hours the counter should start from 20 hours for that user. I hope it's clear enough. I found that if that is possible it could be done using cookies, but I'm not sure how it should be done... If anyone could help it will be great! :3
Here is my code so far:
HTML:
<div id="clockdiv">
<span class="days"></span>
<span class="hours"></span>
<span class="minutes"></span>
<span class="seconds"></span>
</div>
JavaScript
// if there's a cookie with the name myClock, use that value as the deadline
if(document.cookie && document.cookie.match('myClock')){
// get deadline value from cookie
var deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
}
// otherwise, set a deadline 10 minutes from now and
// save it in a cookie with that name
else{
// create deadline 10 minutes from now
var timeInMinutes = 1380;
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInMinutes*60*1000);
// store deadline in cookie for future reference
document.cookie = 'myClock=' + deadline + '; path=/; domain=.optic2n.com';
}
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
initializeClock('clockdiv', deadline);
Thank you in advance for the help! :3
Best regards,
Tsvetko Krastev
It is possible I have missed something, but your code seems very complex for something so simple. Here is what I came up with:
HTML:
<div id="clockdiv">
<span id="d" class="days"></span>days
<span id="h" class="hours"></span>hrs
<span id="m" class="minutes"></span>mins
<span id="s" class="seconds"></span>secs
</div>
Javascript:
var deadline = localStorage.getItem('dl') ? parseInt(localStorage.getItem('dl')) : (Date.now() + 86400000);
var delay = null;
// Good spot to do checks for 24hrs has passed already here
localStorage.setItem('dl',deadline);
function render() {
if (delay) {
clearTimeout(delay);
delay = null;
}
var diff = (deadline - Date.now()) / 1000;
document.getElementById('d').innerHTML = Math.floor(diff / 86400);
document.getElementById('h').innerHTML = Math.floor(diff / 3600);
document.getElementById('m').innerHTML = Math.floor((diff / 60) % 60);
document.getElementById('s').innerHTML = Math.floor(diff % 60);
delay = setTimeout(render,1000);
}
render();
NOTE: There are no checks for what to do after 24 hours.
I have a page with a JavaScript countdown and Bootstrap's tooltip JavaScript. They work very well, until I reload the page with jQuery's load(); function.
After I trigger load(); function couple of seconds after page load, other JavaScript stops working.
Check my page: http://areafordemos.freeoda.com/reload.html
I don't understand why simple refresh is causing that, and how to solve this problem? I tried to place JavaScript code to other places but no help.
Here is my Javascript code:
//JavaScript code for load() after few seconds.
setTimeout(function(){
$().ready(function() {
$(".reloadthis").load("reload.html .reloadthis");
});
}, 5000);
//JavaScript code for tooltip.
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
//JavaScript code for countdown
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.now();
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
if (t.total <= 0) {
document.getElementById("clockdiv").className = "hidden-div";
document.getElementById("timeIsNow").className = "visible-div";
clearInterval(timeinterval);
return true;
}
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var deadline = '2016-01-01T12:00:00+02:00';
console.log(deadline);
initializeClock('clockdiv', deadline);
When you bind an event to an element in javascript, the handler will live on the element itself rather than keeping a reference to it's class so when you reload new contents in the page, the JS won't be bound to them anymore.
You can do (atleast) two things to fix your issue.
One of them would be to re-run your JS by redoing the function calls.
e.g. Whenever you do $.load you can add a callback that should run after it's done fetching the contents of the page.
For instance:
$('.reloadthis').load('reload.html .reloadthis', function(resp, status, xhr) {
call_functions_again(); // psuedo, you'd want to re-call your functions here to make them work with ajax loaded content
});
You could also try looking into event delegation but this serves different purposes like automatically binding events to newly added elements in the DOM by listening on the parent instead and letting the event bubble to children.