Hello
I have a problem with countdown by javascript, i wrote a script and not bad.
i need reload countdown after few minute by ajax (json) but after loading new data script does not work properly.
after obtaining a new time counting time pours or not display!
help me pleas
thanks :)
var d = today();
function today(){
now = new Date().getTime();
return Math.round(now/1000);
}
function countdown(time1,id)
{
off = today() - d;
time = time1 - off;
h = Math.floor(time / 3600);
m = Math.floor(time / 60) % 60;
s = time % 60;
t = h + ":";
if(m < 10){ t += "0"; }
t += m + ":";
if (s < 10) { t += "0"; }
t += s;
//done
if(m <= 0 && s <= 0){
$("#"+id).html("00:00:00");
return;
}
$("#"+id).html(t).show();
var sto = window.setTimeout("countdown('"+time1+"','"+id+"')", 1000);
}
$(document).ready(function(){
//clearTimeout(sto);
countdown(1000, 'timer1');
countdown(1200, 'timer2');
//example (instead of json)
setTimeout(function(){
countdown(3000, 'timer1');
countdown(3200, 'timer2');
//alert('after click ok scripts is worked!');
}, 3000)
});
You can reset a timeout by doing window.clearTimeout(sto).
James Khoury suggests removing the var keyword from sto after declaring var sto; in the global namespace.
Below I summarize how to do these kinds of timing things in javascript:
Let's begin with some date and time manipulation functions:
// Time functions
// default unit is the millisecond
var sec = 1000;
var ms = 1;
function formatSeconds(time) {
var seconds = Math.floor(time/1000);
with (Math) {
var sec = seconds % 60;
var min = floor(seconds/60) % 60;
var hr = floor(seconds/3600);
}
return hr+':'+min+':'+sec;
}
function now() {
return (new Date()).getTime();
}
Now the actual interesting code:
// Timeout functions
function callPeriodically(params) {
/*
* PARAMS: {callback=function, callbackInterval=int, cleanupCallback=function}
*
* WHAT THIS FUNCTION DOES:
* Calls [[callback()]] every [[callbackInterval]] milliseconds;
* (The [[callback()]] function should return false if it wishes
* to abort callbacks.)
*
* RETURN VALUE: a function which, when called, will abort the periodic callbacks.
*
* Nomatter how periodic callbacks are aborted, the [[cleanupCallback()]] function
* is always run last thing.
*/
var callback = params['callback'];
var callbackInterval = params['callbackInterval'];
var cleanupCallback = params['cleanup'];
var timeout = window.setTimeout(makeClock());
var timer = function() {
if (callback()) # stop if callback() returns false
timeout = window.setTimeout(timer, callbackInterval);
else if (cleanupCallback)
cleanupCallback();
};
var cancel = function() {
window.clearTimeout(timeout);
cleanupCallback();
}
return cancel;
}
Making a clock callback which uses the above machinery:
function makeClockCallback(duration, htmlId) {
// enclose endTime in a closure:
var startTime = now();
var endTime = startTime + duration;
var countdown = function() {
var timeLeft = endTime - now();
$('#'+htmlId).html(formatSeconds(timeLeft));
return timeLeft>0; # continue as long as timeLeft>0
};
return countdown;
}
Now let's test it:
// Demo
function makeAndRunClock(htmlId) {
return callPeriodically({
callback = makeClockCallback(1000*sec, htmlId),
callbackInterval = 1000*ms,
cleanupCallback = function() {
alert(htmlId+' has been cancelled!');
}
);
}
var abortClock1 = makeAndRunClock(7*sec); // will naturally stop after 7sec
var abortClock2 = makeAndRunClock(10*sec); // will naturally stop after 10sec
window.setTimeout(
function() {
abortClock1(); // force clock1 to stop after 4sec
},
4*sec
);
There are a few syntax errors, but there you go.
Related
My 14 yr old son is working on a Science Project looking at reaction time and age. He is setting up a little web app to test people - When a page is loaded a timer starts and there is a delay in a STOP button appearing (4 secs for this example). When they click the stop button, the timer stops.
He's done a great job of coding all of that so far. He is using a piece of JavaScript that he found and has modified it to his needs.
His issue - how to pass the stopped time into a variable and then pass that to another page. He is able to successfully do it if the variable is static ie "Hello."
What is wrong with the function stop(); in this example? He currently gets a [object HTMLSpanElement]
var clsStopwatch = function() {
// Private vars
var startAt = 0; // Time of last start / resume. (0 if not running)
var lapTime = 0; // Time on the clock when last stopped in milliseconds
var now = function() {
return (new Date()).getTime();
};
// Public methods
// Start or resume
this.start = function() {
startAt = startAt ? startAt : now();
};
// Stop or pause
this.stop = function() {
// If running, update elapsed time otherwise keep it
lapTime = startAt ? lapTime + now() - startAt : lapTime;
startAt = 0; // Paused
};
// Reset
this.reset = function() {
lapTime = startAt = 0;
};
// Duration
this.time = function() {
return lapTime + (startAt ? now() - startAt : 0);
};
};
var x = new clsStopwatch();
var $time;
var clocktimer;
function pad(num, size) {
var s = "0000" + num;
return s.substr(s.length - size);
}
function formatTime(time) {
var h = m = s = ms = 0;
var newTime = '';
h = Math.floor( time / (60 * 60 * 1000) );
time = time % (60 * 60 * 1000);
m = Math.floor( time / (60 * 1000) );
time = time % (60 * 1000);
s = Math.floor( time / 1000 );
ms = time % 1000;
newTime = pad(h, 2) + ':' + pad(m, 2) + ':' + pad(s, 2) + ':' + pad(ms, 3);
return newTime;
}
function update() {
$time.innerHTML = formatTime(x.time());
}
function start() {
$time = document.getElementById('time');
update();
clocktimer = setInterval("update()", 1);
x.start();
$(document).ready(function() { $('#mybutton').delay(4000).fadeIn(0);});
}
function stop() {
x.stop();
//var varTime = "Hello";
var varTime = document.getElementById('time');
window.location.href = "somephpfile.php?etime=" + varTime;
}
The var varTime = document.getElementById('time') is assigning the element to the varible, which is fine and not a bad option however I believe your son only needs the HTML text of that element.
There are two options. The first option keeps the time element in the function for possible expansion later.
function stop() {
x.stop();
var varTime = document.getElementById('time');
if (varTime) {
window.location.href = "somephpfile.php?etime=" + varTime.innerHTML;
}
}
Or just extract the required text and send it - even if it is empty.
function stop() {
x.stop();
if (document.getElementById('time')) {
window.location.href = "somephpfile.php?etime=" + document.getElementById('time').innerHTML;
}
}
You need to read the innerHTML of the element instead if just reading element itself. This can be accomplished by :
function stop() {
x.stop();
//var varTime = "Hello";
var varTime = document.getElementById('time').innerHTML;
window.location.href = "somephpfile.php?etime=" +
}
I want to get the time difference in between two clicks on a single button.
I have my markup like this
click here
I am using this code to get the time difference between two clicks.
var clickedTime = '';
var lastClicked = '';
$('body').on('click', 'a', function(e) {
var d = new Date();
clickedTime = lastClicked;
lastClicked = d.getTime();
console.log(clickedTime);
console.log(lastClicked);
});
But its showing the same time in both console. So can someone tell me how to get the time difference?
Here is a simple jQuery function to return the time difference in the desired format for every x clicks - Demo
<button>Get Time Difference</button>
(function ($) {
$.fn.clickTimer = function ($param, $numbClicks) {
function msTotime(ms) {
var mill = ms % 1000;
var seconds = Math.floor((ms / 1000) % 60);
var minutes = Math.floor((ms / (60 * 1000)) % 60);
switch ($param) {
case "ms":
return ms;
break;
case "s":
return seconds;
break;
default:
return [minutes, seconds, mill];
}
}
var counter = 0;
var Start_Time;
this.click(function (event) {
counter++;
if (counter == $numbClicks) {
counter = 0;
var now = event.timeStamp;
Diff = now - Start_Time;
console.log(msTotime(Diff));
} else {
Start_Time = event.timeStamp;
}
});
return this;
};
})(jQuery);
Usage :
$(selector).clickTimer(time format , number of clicks);
$("button").clickTimer("ms", 2);
// returns time difference in milliseconds for every 2 clicks
$("button").clickTimer("s", 2);
// returns time difference in seconds
$("button").clickTimer(false, 2);
// returns an array [minutes, seconds, milliseconds]
Let me know what you think. This is definitely not a perfect solution but it may get you started.
You can use Date.prototype.getTime() to get time of click event.
var click = 0;
var time;
var difference;
$("a").click(function(){
var date = new Date();
click += 1;
if (click == 2) {
difference = date.getTime() - time;
click = 0;
console.log(difference);
}
else
time = date.getTime();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<a>Please double click on me!</a>
Or use Event.timeStamp property of event.
var click = 0;
var time;
var difference;
$("a").click(function(e){
click += 1;
if (click == 2) {
difference = e.timeStamp - time;
click = 0;
console.log(difference);
}
else
time = e.timeStamp;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<a>Please double click on me!</a>
Note that the codes return diffrence time in milisecond.
I have the following lines of code on my web page - example/demo.
HTML:
<p class="countdown-timer">10:00</p>
<p class="countdown-timer">10:00</p>
JavaScript:
function startTimer(duration, display) {
var start = Date.now(),
diff,
minutes,
seconds;
function timer() {
// get the number of seconds that have elapsed since
// startTimer() was called
diff = duration - (((Date.now() - start) / 1000) | 0);
// does the same job as parseInt truncates the float
minutes = (diff / 60) | 0;
seconds = (diff % 60) | 0;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (diff <= 0) {
// add one second so that the count down starts at the full duration
// example 05:00 not 04:59
start = Date.now() + 1000;
}
};
// we don't want to wait a full second before the timer starts
timer();
setInterval(timer, 1000);
}
$(document).ready(function(){
// set the time (60 seconds times the amount of minutes)
var tenMinutes = 60 * 10,
display = document.querySelector('.countdown-timer');
startTimer(tenMinutes, display);
});
As I'm relatively new to JavaScript/jQuery, how would I be able to make the timer stop on 0 and so that the second clock also works?
I have tried replacing document.querySelector('.countdown-timer'); with $('.countdown-timer');
I created a class to do that a while ago, for one of my projects. It allows you to have multiple counters, with different settings. It can also be configured to be paused or reset with a button, using the available functions. Have a look at how it's done, it might give you some hints:
/******************
* STOPWATCH CLASS
*****************/
function Stopwatch(config) {
// If no config is passed, create an empty set
config = config || {};
// Set the options (passed or default)
this.element = config.element || {};
this.previousTime = config.previousTime || new Date().getTime();
this.paused = config.paused && true;
this.elapsed = config.elapsed || 0;
this.countingUp = config.countingUp && true;
this.timeLimit = config.timeLimit || (this.countingUp ? 60 * 10 : 0);
this.updateRate = config.updateRate || 100;
this.onTimeUp = config.onTimeUp || function() {
this.stop();
};
this.onTimeUpdate = config.onTimeUpdate || function() {
console.log(this.elapsed)
};
if (!this.paused) {
this.start();
}
}
Stopwatch.prototype.start = function() {
// Unlock the timer
this.paused = false;
// Update the current time
this.previousTime = new Date().getTime();
// Launch the counter
this.keepCounting();
};
Stopwatch.prototype.keepCounting = function() {
// Lock the timer if paused
if (this.paused) {
return true;
}
// Get the current time
var now = new Date().getTime();
// Calculate the time difference from last check and add/substract it to 'elapsed'
var diff = (now - this.previousTime);
if (!this.countingUp) {
diff = -diff;
}
this.elapsed = this.elapsed + diff;
// Update the time
this.previousTime = now;
// Execute the callback for the update
this.onTimeUpdate();
// If we hit the time limit, stop and execute the callback for time up
if ((this.elapsed >= this.timeLimit && this.countingUp) || (this.elapsed <= this.timeLimit && !this.countingUp)) {
this.stop();
this.onTimeUp();
return true;
}
// Execute that again in 'updateRate' milliseconds
var that = this;
setTimeout(function() {
that.keepCounting();
}, this.updateRate);
};
Stopwatch.prototype.stop = function() {
// Change the status
this.paused = true;
};
/******************
* MAIN SCRIPT
*****************/
$(document).ready(function() {
/*
* First example, producing 2 identical counters (countdowns)
*/
$('.countdown-timer').each(function() {
var stopwatch = new Stopwatch({
'element': $(this), // DOM element
'paused': false, // Status
'elapsed': 1000 * 60 * 10, // Current time in milliseconds
'countingUp': false, // Counting up or down
'timeLimit': 0, // Time limit in milliseconds
'updateRate': 100, // Update rate, in milliseconds
'onTimeUp': function() { // onTimeUp callback
this.stop();
$(this.element).html('Go home, it\'s closing time.');
},
'onTimeUpdate': function() { // onTimeUpdate callback
var t = this.elapsed,
h = ('0' + Math.floor(t / 3600000)).slice(-2),
m = ('0' + Math.floor(t % 3600000 / 60000)).slice(-2),
s = ('0' + Math.floor(t % 60000 / 1000)).slice(-2);
var formattedTime = h + ':' + m + ':' + s;
$(this.element).html(formattedTime);
}
});
});
/*
* Second example, producing 1 counter (counting up to 6 seconds)
*/
var stopwatch = new Stopwatch({
'element': $('.countdown-timer-up'),// DOM element
'paused': false, // Status
'elapsed': 0, // Current time in milliseconds
'countingUp': true, // Counting up or down
'timeLimit': 1000 * 6, // Time limit in milliseconds
'updateRate': 100, // Update rate, in milliseconds
'onTimeUp': function() { // onTimeUp callback
this.stop();
$(this.element).html('Countdown finished!');
},
'onTimeUpdate': function() { // onTimeUpdate callback
var t = this.elapsed,
h = ('0' + Math.floor(t / 3600000)).slice(-2),
m = ('0' + Math.floor(t % 3600000 / 60000)).slice(-2),
s = ('0' + Math.floor(t % 60000 / 1000)).slice(-2);
var formattedTime = h + ':' + m + ':' + s;
$(this.element).html(formattedTime);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
These 2 timers should count down from 10 minutes to 0 seconds:
<p class="countdown-timer">00:10:00</p>
<p class="countdown-timer">00:10:00</p>
But this one will count from 0 to 6 seconds:
<p class="countdown-timer-up">00:00:00</p>
I think your problem is you are passing an array into the startTimer function so it is just doing it for the first item.
If you change the document ready so that you initiate a timer for each instance of .countdown-timer, it should work:
// set the time (60 seconds times the amount of minutes)
var tenMinutes = 60 * 10;
$('.countdown-timer').each(function () {
startTimer(tenMinutes, this);
});
Example
document.querySelector('.class') will only find first element with .class. If you're already using jQuery I would recommend to do this:
var display = $('.countdown-timer');
for (var i = 0; i < display.length; i++) {
startTimer(tenMinutes, display[i]);
}
This way it will work for any number of countdown timers.
Here we go, jsfiddle
just changed the querySelector to getElementsByClassName to get all p elements with the same class. You can than start your timer on the different elements by using it's index.
No need for a queue :D
$(document).ready(function(){
// set the time (60 seconds times the amount of minutes)
var tenMinutes = 60 * 10,
display = document.getElementsByClassName('countdown-timer');
startTimer(tenMinutes, display[0]);
startTimer(tenMinutes, display[1]);
});
I’m looking for a way to tweak a current script of mine that loads a page into a div every minute. I want it to wait 5 minutes at a specific time, then go back to executing every minute. Here’s what I have so far.
var starttime = 10:30:00 PM;
var endtime = 10:35:00 PM;
var myVar = setInterval(function(){ myTimer() }, 1000);
function myTimer() {
var d = new Date();
document.getElementById("currenttime").innerHTML = d.toLocaleTimeString();
if ( d.toLocaleTimeString() > starttime &&
d.toLocaleTimeString() < endtime ) {
setInterval(function() {
}, 300000);
$("#ticketload").load("loadlasttenminutesmodified.php");
} else {
setInterval(function() {
}, 60000);
$("#ticketload").load("loadlasttenminutesmodified.php");
}
};
Any help is appreciated, thanks.
var starttime = '10:30:00 PM',
endtime = '10:35:00 PM';
var myVar = setInterval(myTimer, 1000);
// Use this function instead of toLocaleTimeString,
// since inconsistencies may arise with that one, depending on country.
function getTimeFormatted(date) {
var hours = date.getHours(),
minutes = date.getMinutes(),
seconds = date.getSeconds(),
ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
return hours + ':' + minutes + ':' + seconds + ' ' + ampm;
}
function myTimer() {
var d = getTimeFormatted(new Date());
document.getElementById("currenttime").innerHTML = d;
// Simply return (exit) the function when current time is
// between both of those dates.
// Your function will not go further than this.
// And it will effectively do nothing other than update the innerHTML
// for about five minutes.
if (d > starttime && d < endtime) return;
// Do the stuff that is supposed to run every minute.
// I assume this is, but place whatever else you want in here.
$("#ticketload").load("loadlasttenminutesmodified.php");
}
You can just exit out of the interval with return when the time criteria is met, before executing the rest of the code that is supposed to run every minute.
I made some changes to your code:
You missed quotes in your starttime and endtime variables
Replaced toLocaleTimeString with a new function. Thanks to #SpiderPig for pointing out why toLocaleTimeString isn't reliable.
You can specify the function directly in the myVar interval, instead of executing the myTimer function inside of an anonymous function.
Format the current day into AM/PM once, since that's all that is needed.
return when the time criteria is met and before executing the rest of the code inside of the interval.
I don't know what those empty setIntervals were in there for, so I removed them. I guess this is just example code, judging from the variable names you gave.
Try
var startTime = "22:30:00",
endTime = "22:35:00",
currentTime = $("#currenttime"),
ticketLoad = $("#ticketload"),
delay = 60000,
extendedDelay = delay * 5,
timeout = null,
timer = function timer(delay) {
var cycle = function cycle(delay, reset) {
// clear `queue` if within `startTime` , `endTime` range,
// `reset` set to `true`
if (reset) {
this.queue("timer", []);
};
// `cycle` delay `60000`
this.html("currenttime called at:" + new Date().toLocaleString())
// set `cycle` delay to `300000`
// if within `startTime` , `endTime` range,
// `reset` set to `true`
var _delay = !reset ? delay : extendedDelay;
.delay(_delay, "timer")
.queue("timer", function() {
console.log(new Date().toLocaleString());
// continue cycle
timer.call($(this), _delay);
}).dequeue("timer");
// do ajax stuff
ticketLoad.load("loadlasttenminutesmodified.php")
.fail(function(jqxhr, textStatus, errorThrown) {
console.log(errorThrown);
// clear `queue` on `error`
currentTime.queue("timer", [])
});
};
// if within `startTime` , `endTime` range
// clear `queue` , set `cycle` delay to `300000`
if (String(new Date()).split(" ")[4] > startTime
&& String(new Date()).split(" ")[4] < endTime) {
cycle.call(this, delay, true);
timeout = setInterval(function() {
if (String(new Date()).split(" ")[4] >= endTime) {
clearInterval(timeout);
timeout = null;
this.queue("timer", []);
cycle.call(this, delay)
}
}.bind(this), 7500)
} else {
if (String(new Date()).split(" ")[4] >= endTime) {
this.queue("timer", []);
cycle.call($(this), delay)
} else {
cycle.call($(this), delay)
}
};
};
timer.call(currentTime, delay);
$(function() {
var startTime = "22:30:00",
endTime = "22:35:00",
currentTime = $("#currenttime"),
ticketLoad = $("#ticketload"),
delay = 60000,
extendedDelay = delay * 5,
timeout = null,
timer = function timer(delay, reset) {
var cycle = function cycle(delay, reset) {
if (reset) {
this.queue("timer", [])
};
var _delay = !reset ? delay : extendedDelay;
this.html("currenttime called at:" + new Date().toLocaleString())
.delay(_delay, "timer")
.queue("timer", function() {
console.log(new Date().toLocaleString());
timer.call($(this), _delay)
}).dequeue("timer");
$.when(ticketLoad)
.always(function(data) {
this.html("ticketLoad called at:" + new Date().toLocaleString())
})
};
if (String(new Date()).split(" ")[4] > startTime
&& String(new Date()).split(" ")[4] < endTime) {
cycle.call(this, delay, true);
timeout = setInterval(function() {
if (String(new Date()).split(" ")[4] >= endTime) {
clearInterval(timeout);
timeout = null;
this.queue("timer", []);
cycle.call(this, delay)
}
// check if beyond `endTime` ,
// reset `cycle`
// adjust interval duration here
// for greater, less frequency of checks
}.bind(this), 7500)
} else {
if (String(new Date()).split(" ")[4] >= endTime) {
this.queue("timer", []);
cycle.call($(this), delay)
} else {
cycle.call($(this), delay)
}
};
};
timer.call(currentTime, delay)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="currenttime"></div>
<div id="ticketload"></div>
Date.prototype.setMyTime = function (time) {
arrTime = time.split(":");
this.setHours(arrTime[0],arrTime[1],arrTime[2]);
return this;
}
var d = new Date();
var starttime = d.setMyTime('22:30:00');
var endtime = d.setMyTime('22:35:00');
var intervalId, loading = false;
var myVar = setInterval(function(){ myTimer() }, 1000);
function myTimer() {
var d = new Date();
document.getElementById("currenttime").innerHTML = d.toLocaleTimeString();
if(d.getTime() > starttime.getTime() && d.getTime() < endtime.getTime()) {
clearInterval(intervalId);
loading = false;
} else {
if (loading === false) {
intervalId = setInterval(function(){ $("#ticketload").load("loadlasttenminutesmodified.php"); }, 60000);
loading = true;
}
}
}
I decided to take a different approach. Set the interval to one minute and have and if statement inside that. Also, I needed to convert the time format into the same format as my variables.
<script type="text/javascript">
starttime = '10:30:00 PM';
endtime = '10:35:00 PM';
var myVar = setInterval(function(){ myTimer() }, 60000);
function myTimer() {
var timenow = new Date();
timeconvert = timenow.toLocaleTimeString()
if (timeconvert > starttime && timeconvert < endtime)
{
//alert("Time is 5 minutes");
}
else
{
//alert("Time is 60 seconds");
$("#ticketload").load("loadlasttenminutesmodified.php");
}
};
</script>
This has been working great all week.
I have an annoying problem, i have trying to implement a simple 10 or 15 minute recurrent countdown. i have tried jQuery but it just gives me options to count down to a date and stops after the countdown is finished.
I found the below code Here but i cant figure it to remove the days and make it to count down for 10 or 15 minuters. Can someone please help me?
<div id="countre3">Loading...</div>
<script type="text/javascript">
function mycountre(o, timeArray){
var countre = document.getElementById(o);
if(!countre) {
return;
}
// helper functions
function mksec(day, h, m, s){ return day*24*60*60+h*60*60+m*60+s; }
function toTimeString(sec, showZero){
var d=Math.floor(sec/(60*60*24))
var h=Math.floor(sec/(60*60)%24);
var m=Math.floor((sec/60) % 60);
var s=sec % 60;
var ret=d+'days '+h+'hrs '+m+'min '+s+'sec';
if(showZero){
return ret;
}else if(d==0 && h==0 && m==0){
return s+'sec';
}else if(d==0){
return h+'hrs '+m+'min '+s+'sec';
}else if(d==0 && h==0){
return m+'min '+s+'sec';
}else {
return ret;
}
}
//
var secArray = [];
var dayNow = new Date().getDay();
for(var i=0;i<timeArray.length;i++){
var day=timeArray[i][0];
if(day==-1){
day=dayNow;
}
secArray.push({
day: timeArray[i][0],
sec: mksec(day, timeArray[i][2], timeArray[i][2], timeArray[i][3]),
msg: timeArray[i][4] || false,
showZero: timeArray[i][5] || false
});
}
secArray.sort(function(a,b){ return a.sec-b.sec;});
// timer code - will be called around each second (~1000 ms)
function updatecountre(){
// get current UTC time in seconds
var d=new Date();
var secNow = mksec(d.getDay(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds());
// find next event
var nextIndex=0;
for(var i=0;i<secArray.length; i++){
var diff = secArray[i].sec-secNow;
if(diff>0){
nextIndex=i;
break;
}
}
//
var diff=secArray[nextIndex].sec-secNow;
var prevDiff=diff;
if(diff<0){
var dayDiff = 6-secArray[nextIndex].day;
if(secArray[nextIndex].day == -1){
dayDiff=0;
}
diff=(dayDiff+1)*24*60*60-Math.abs(diff);
}
var str='';
// get message if there is any set
if(secArray[nextIndex].msg){
str=secArray[nextIndex].msg;
}
var timeString = toTimeString(diff, secArray[nextIndex].showZero);
if(str.match('#{countre}')!=null){
str=str.replace(/#{countre}/, timeString);
}else if(str.indexOf(' ')==0){ // message starts with space
str=timeString+str;
}else{ // no specific hint where to put countre, so display it after message
str+=timeString;
}
countre.innerHTML=str;
}
setInterval(updatecountre, 1000);
};
mycountre('countre3', [ [5, 5, 0, 0, '<center><b>Next Turns are Due in </b><p class="smalltext"> #{countre}</center>', false] ]);
</script>
Try this:
function mycountre(countdownId, countdownSeconds, countdownLooping){
var countre = document.getElementById(countdownId); // get html element
if (!countre) {
return;
}
var target = new Date().getTime() + 1000 * countdownSeconds; // target time
var intervalId; // id of the interval
// update function
function updatecountre(){
var time = Math.floor((target - new Date().getTime()) / 1000); // countdown time in seconds
if (time < 0) { // if countdown ends
if (countdownLooping) { // if it should loop
target += 1000 * countdownSeconds; // set new target time
time = Math.floor((target - new Date().getTime()) / 1000); // recalculate current time
} else { // otherwise
clearInterval(intervalId); // clear interval
time = 0; // set time to 0 to avoid displaying negative values
}
}
// split time to seconds, minutes and hours
var seconds = '0' + (time % 60);
time = (time - seconds) / 60;
var minutes = '0' + (time % 60);
time = (time - minutes) / 60;
var hours = '0' + time;
// make string from splited values
var str = hours.substring(hours.length - 2) + ':' + minutes.substring(minutes.length - 2) + ':' + seconds.substring(seconds.length - 2);
countre.innerHTML = str;
}
intervalId = setInterval(updatecountre, 200); // start interval to execute update function periodically
};
mycountre(
'countre3', // id of the html element
15 * 60, // time in seconds (15min here)
true // loop after countdown ends?
);
Working demo: http://jsfiddle.net/Xv3jx/1/
Small attempt for a jQuery plugin - more generic without minute/hour calc to avoid that the exaple gets too big:
(function($) {
$.fn.countdown = function(params) {
this.each(function() {
container = $.extend({
t: $(this),
stepSize: 1000, // milliseconds
duration: 3600, // seconds
offset: 0,
stepCallback: function() {},
finishCallback: function() {},
interval: function() {
if (this.offset>this.duration) {
this.finishCallback();
} else {
this.stepCallback();
}
this.offset += this.stepSize/1000;
}
}, params);
setInterval(function() {
container.interval();
}, container.stepSize);
});
return this;
};
})(jQuery);
Can be used with:
$('.main').countdown({
stepCallback: function() { console.log('step');},
finishCallback: function() { console.log('done');}
});
A simple countdown would then be implemented like this:
$('.main').countdown({
duration: 300,
stepCallback: function() {
var time = this.duration-this.offset
var seconds = '0' + (time % 60);
time = (time - seconds) / 60;
var minutes = '0' + (time % 60);
time = (time - minutes) / 60;
var hours = '0' + time;
var str = hours.substring(hours.length - 2) + ':' + minutes.substring(minutes.length - 2) + ':' + seconds.substring(seconds.length - 2);
$(this.t).html(str);
},
finishCallback: function() { $(this.t).html('tadaaa'); }
});
Cheers