I have been trying to find a script (preferably JavaScript) for a countdown timer for a specific time and date (i.e. 9am GMT June 17th 2013). When the countdown completes (i.e it is after 9am GMT on June 17th), I want the site to start redirecting automatically to another page.
I actually wrote a simple countdown script for when we were having LAN parties with coworkers :-)
I didn't take the time to make it a jQuery plugin and it has a weird structure, but it works and you can modify it to your needs.
http://jsfiddle.net/Y6n9W/
(function($, undefined) {
countdown = function(settings) {
var _this = this,
defaults = {
end: '30.09.2012 09:00'
}, rDate = /(\d+).(\d+).(\d+) (\d+):(\d+)/;
_this.settings = $.extend(defaults, settings);
var matches = _this.settings.end.match(rDate);
_this.endDate = new Date(matches[3], matches[2] - 1, matches[1], matches[4], matches[5], 0, 0);
_this.nDays = $('<span />').addClass('countdown days').html('0');
_this.nHours = $('<span />').addClass('countdown hours').html('0');
_this.nMinutes = $('<span />').addClass('countdown minutes').html('0');
_this.nSeconds = $('<span />').addClass('countdown seconds').html('0');
_this.settings.element.append(
$('<span />').append(
_this.nDays,
' Days'
),
$('<span />').append(
_this.nHours,
' Hours'
),
$('<span />').append(
_this.nMinutes,
' Minutes'
),
$('<span />').append(
_this.nSeconds,
' Seconds'
)
);
countdownMethods.start.call(_this);
return _this;
};
var countdownMethods = {
start: function() {
var _this = this,
interval = 0;
var updateTime = function() {
var now = new Date(),
diff = Math.round((_this.endDate - now) / 1000);
if(diff < 0) {
diff = 0;
clearInterval(interval);
window.location.href = 'newurl..';
}
var days = Math.floor(diff/86400);
diff -= days * 86400;
var hours = Math.floor(diff/3600);
diff -= hours * 3600;
var minutes = Math.floor(diff/60);
diff -= minutes * 60;
_this.nDays.html(days);
_this.nHours.html(hours);
_this.nMinutes.html(minutes);
_this.nSeconds.html(diff);
};
updateTime();
interval = setInterval(function() {
updateTime();
}, 1000);
}
};
})(jQuery);
And you use it like this:
$(function() {
var counter = countdown({
end: '08.05.2013 15:15',
element: $('div')
});
});
Related
How to make multiple countdown timers at the same page using the codes below?
I tried to make another countdown timer by making another var start = document.getElementById("start2"); and var dis = document.getElementById("display2"); but when I click the 1 button only the second countdown timer is working,
var start1 = document.getElementById("start1");
var dis1 = document.getElementById("display1");
var finishTime1;
var timerLength1 = 10;
var timeoutID1;
dis1.innerHTML = "" + timerLength1;
if(localStorage.getItem('myTime')){
Update();
}
start1.onclick = function () {
localStorage.setItem('myTime', ((new Date()).getTime() + timerLength1 * 1000));
if (timeoutID1 != undefined) window.clearTimeout(timeoutID1);
Update();
}
function Update() {
finishTime1 = localStorage.getItem('myTime');
var timeLeft = (finishTime1 - new Date());
dis1.innerHTML = "" + Math.max(timeLeft/1000,0)
timeoutID1 = window.setTimeout(Update, 100);
}
var start2 = document.getElementById("start2");
var dis2 = document.getElementById("display2");
var finishTime2;
var timerLength = 100;
var timeoutID;
dis2.innerHTML = "" + timerLength;
if(localStorage.getItem('myTime')){
Update();
}
start2.onclick = function () {
localStorage.setItem('myTime', ((new Date()).getTime() + timerLength * 1000));
if (timeoutID != undefined) window.clearTimeout(timeoutID);
Update();
}
function Update() {
finishTime2 = localStorage.getItem('myTime');
var timeLeft = (finishTime2 - new Date());
dis2.innerHTML = "" + Math.max(timeLeft/1000,0)
timeoutID = window.setTimeout(Update, 100);
}
<span id="display2"></span><button id="start1">START1</button>
<br><br>
<span id="display2"></span><button id="start1">START1</button>
enter code here
You are using the same id for localStorage. Actually it is better to create isolated context through function or class, then it will be easier to handle as much counters as you wish. Also you can use setInterval instead of setTimer
One more tip: when you assign number to string field no need to write "" + value, because number authomatically will be converted into string
const createCounter = (startElementId, displayElementId, localStorageId, timerLength) => {
const startElement = document.getElementById(startElementId),
displayElement = document.getElementById(displayElementId)
let timeoutID
displayElement.innerHTML = timerLength
const storageValue = localStorage.getItem(localStorageId)
if (storageValue) startTimer()
startElement.onclick = () => {
const value = (new Date()).getTime() + timerLength * 1000
localStorage.setItem(localStorageId, value)
startTimer()
}
function startTimer () {
if (timeoutID) clearInterval(timeoutID)
timeoutId = setInterval(updateTime, 100)
}
function updateTime (finishTime) {
finishTime = finishTime || localStorage.getItem(localStorageId)
const timeLeft = finishTime - new Date()
displayElement.innerHTML = Math.max(timeLeft / 1000, 0)
}
}
// run first timer for elements with ids start1 and display1
createCounter('start1', 'display1', 'someId1', 10)
// run second timer for elements with ids start1 and display1
createCounter('start2', 'display2', 'someId2', 60)
html
<button id=start1>Start</button>
<div id=display1></div>
<button id=start2>Start</button>
<div id=display2></div>
I am trying to put together a stopwatch using JavaScript. I have got the date to populate with the correct information but my Stopwatch doesn't work. I click start and the numbers never move from 0, I would like to have it increment in MS no seconds. I have my code for the JS and the HTML also. HTML is functioning as it should but the JS is not. I am very green to the JavaScript world and i have looked and looked and was unable to come across a solution that would be a benefit to me. Thanks for your assistance.
"use strict";
var $ = function(id) { return document.getElementById(id); };
var stopwatchTimer;
var elapsedMinutes = 0;
var elapsedSeconds = 0;
var elapsedMilliseconds = 0;
var displayCurrentTime = function() {
var now = new Date();
var hours = now.getHours();
var ampm = "AM";
if (hours > 12) {
hours = hours - 12;
ampm = "PM";
} else {
switch (hours) {
case 12:
ampm = "PM";
break;
case 0:
hours = 12;
ampm = "AM";
}
}
$("hours").firstChild.nodeValue = hours;
$("minutes").firstChild.nodeValue = padSingleDigit(now.getMinutes());
$("seconds").firstChild.nodeValue = padSingleDigit(now.getSeconds());
$("ampm").firstChild.nodeValue = ampm;
};
var padSingleDigit = function(num) {
if (num < 10) { return "0" + num; }
else { return num; }
};
var tickStopwatch = function() {
// I also need to increment in 10 milliseconds increments but unsure if I //have this right
var ms=0;
var sec=0;
var min=0;
var frame= function() {
If(ms==1000)
ms=0;
sec++;
}
if(sec==60) {
sec=0;
min++;
document.getElementById("s_seconds").innerHTML = valueOf(sec);
document.getElementById("s_minutes").innerHTML = valueOf(min);
document.getElementById("s_ms").innerHTML = valueOf(ms);
}
};
var startStopwatch = function(evt) {
};
var stopStopwatch = function(evt) {
};
var resetStopwatch = function(evt) {
};
window.onload = function() {
displayCurrentTime();
setInterval(tickStopwatch, 1000);
};
"use strict"; //evt is in a separate file
var evt = {
attach: function(node, eventName, func) {
},
detach: function(node, eventName, func) {
},
preventDefault: function(e) {
}
};
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Clock</title>
<link rel="stylesheet" href="clock.css">
<script src="library_event.js"></script>
<script src="clock.js"></script>
</head>
<body>
<main>
<h1>Digital clock with stopwatch</h1>
<fieldset>
<legend>Clock</legend>
<span id="hours"> </span>:
<span id="minutes"> </span>:
<span id="seconds"> </span>
<span id="ampm"> </span>
</fieldset>
<fieldset>
<legend>Stop Watch</legend>
Start
Stop
Reset
<span id="s_minutes">00</span>:
<span id="s_seconds">00</span>:
<span id="s_ms">000</span>
</fieldset>
</main>
</body>
</html>
If you incrementally update the values ms, seconds, minutes you'll never be accurate. You'll lose time with every update. There simply is no interval that can operate at that speed and accuracy in JS.
Instead, compute them from the internal clock
let offset = 0,
paused = true;
render();
function startStopwatch(evt) {
if (paused) {
paused = false;
offset -= Date.now();
render();
}
}
function stopStopwatch(evt) {
if (!paused) {
paused = true;
offset += Date.now();
}
}
function resetStopwatch(evt) {
if (paused) {
offset = 0;
render();
} else {
offset = -Date.now();
}
}
function format(value, scale, modulo, padding) {
value = Math.floor(value / scale) % modulo;
return value.toString().padStart(padding, 0);
}
function render() {
var value = paused ? offset : Date.now() + offset;
document.querySelector('#s_ms').textContent = format(value, 1, 1000, 3);
document.querySelector('#s_seconds').textContent = format(value, 1000, 60, 2);
document.querySelector('#s_minutes').textContent = format(value, 60000, 60, 2);
if(!paused) {
requestAnimationFrame(render);
}
}
<fieldset>
<legend>Stop Watch</legend>
Start
Stop
Reset
<span id="s_minutes">00</span>:
<span id="s_seconds">00</span>:
<span id="s_ms">000</span>
</fieldset>
offset stores two values: when paused it stores the value at which you stopped, otherwise it stores the offset you have to add to Date.now() to compute the value.
The value is the time in ms, computing seconds and minutes out of it is basic arithmetic.
Your interval function is set to run once per 1000ms (or 1 sec), which won't give you 1ms resolution. In fact, the best you can do is 10ms resolution with setInterval. You also need to increment a counter, which you currently don't do.
Try:
setInterval(tickStopwatch, 10);
var ms = 0;
var tickStopwatch = function() {
var ms += 10;
// rest of your logic
}
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();
});
I want to have a timer in my website like a digital clock. It will have a date and a time in it. I have this following code to do it:
var clockID = 0;
function UpdateClock() {
if(clockID) {
clearTimeout(clockID);
clockID = 0;
}
var tDate = new Date();
var in_hours = tDate.getHours()
var in_minutes=tDate.getMinutes();
var in_seconds= tDate.getSeconds();
if(in_minutes < 10)
in_minutes = '0'+in_minutes;
if(in_seconds<10)
in_seconds = '0'+in_seconds;
if(in_hours<10)
in_hours = '0'+in_hours;
document.getElementById('theTime').innerHTML = ""
+ in_hours + ":"
+ in_minutes + ":"
+ in_seconds;
clockID = setTimeout("UpdateClock()", 1000);
}
function StartClock() {
clockID = setTimeout("UpdateClock()", 500);
}
function KillClock() {
if(clockID) {
clearTimeout(clockID);
clockID = 0;
}
}
But this code is displaying the current computer time so the time doesn't fit with my timezone. What else do i need to add in my code so that it will display date and time according to my timezone? If the date is on DST, it will show the exact time in DST too.
If you need to use JS only, have a look at
add or subtract timezone difference to javascript Date
For example DEMO
var clockID;
var yourTimeZoneFrom = -7.00; //time zone value where you are at
var d = new Date();
//get the timezone offset from local time in minutes
var tzDifference = yourTimeZoneFrom * 60 + d.getTimezoneOffset();
//convert the offset to milliseconds
var offset = tzDifference * 60 * 1000;
function UpdateClock() {
var tDate = new Date(new Date().getTime()+offset);
var in_hours = tDate.getHours()
var in_minutes=tDate.getMinutes();
var in_seconds= tDate.getSeconds();
if(in_minutes < 10)
in_minutes = '0'+in_minutes;
if(in_seconds<10)
in_seconds = '0'+in_seconds;
if(in_hours<10)
in_hours = '0'+in_hours;
document.getElementById('theTime').innerHTML = ""
+ in_hours + ":"
+ in_minutes + ":"
+ in_seconds;
}
function StartClock() {
clockID = setInterval(UpdateClock, 500);
}
function KillClock() {
clearTimeout(clockID);
}
window.onload=function() {
StartClock();
}
In JS you can get the current timezone offset. You need to make adjustment the offset to desired timeZone.
<div id="theTime"></div>
<script>
var clockID = 0;
var requiredTimeZone = 360; // CST (+6:00 hrs)
function UpdateClock() {
if(clockID) {
clearTimeout(clockID);
clockID = 0;
}
var tDate = new Date();
var calculatedTime = tDate.getTime() + (tDate.getTimezoneOffset() * 60000) - (requiredTimeZone * 60000);
tDate.setTime(calculatedTime);
var in_hours = tDate.getHours()
var in_minutes=tDate.getMinutes();
var in_seconds= tDate.getSeconds();
if(in_minutes < 10)
in_minutes = '0'+in_minutes;
if(in_seconds<10)
in_seconds = '0'+in_seconds;
if(in_hours<10)
in_hours = '0'+in_hours;
document.getElementById('theTime').innerHTML = ""
+ in_hours + ":"
+ in_minutes + ":"
+ in_seconds;
clockID = setTimeout("UpdateClock()", 1000);
}
function StartClock() {
clockID = setTimeout("UpdateClock()", 500);
}
function KillClock() {
if(clockID) {
clearTimeout(clockID);
clockID = 0;
}
}
StartClock();
</script>
The current browser timezone offset is added to the browser time and then the desired timezone offset is subtracted to get the required time.
Your required timezone needs to be communicated to the browser in some manner for this to work.
I want to make a countdown timer, that can be used on several places in the same page - so I think it should be a function in some way.
I really want it to be made with jQuery, but I cant quite make it happen with my code. I have e.g. 10 products in a page, that I need to make a countdown timer - when the timer is at 0 I need it to hide the product.
My code is:
$(document).ready(function(){
$(".product").each(function(){
$(function(){
var t1 = new Date()
var t2 = new Date()
var dif = t1.getTime() - t2.getTime()
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
var count = Seconds_Between_dates;
var elm = $(this).attr('id');
alert(elm);
countdown = setInterval(function(){
$(elm + " .time_left").html(count + " seconds remaining!");
if (count == 0) {
$(this).css('display','none');
}
count--;
}, 1000);
});
});
});
EDIT 1:
$(document).ready(function(){
$(".product").each(function(){
var elm = $(this).attr('id');
$(function(){
var t1 = new Date()
var t2 = new Date()
var dif = t1.getTime() - t2.getTime()
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
var count = Seconds_Between_dates;
alert(elm);
countdown = setInterval(function(){
$(elm + " .time_left").html(count + " seconds remaining!");
if (count == 0) {
$(this).css('display','none');
}
count--;
}, 1000);
});
});
});
Do you have any solutions to this?
I'd probably use a single interval function that checks all the products. Something like this:
$(function() {
/* set when a product should expire.
hardcoded to 5 seconds from now for demonstration
but this could be different for each product. */
$('.product').each(function() {
$(this).data('expires', (new Date()).getTime() + 5000);
});
var countdown_id = setInterval(function() {
var now = (new Date()).getTime();
$('.product').each(function() {
var expires = $(this).data('expires');
if (expires) {
var seconds_remaining = Math.round((expires-now)/1000);
if (seconds_remaining > 0) {
$('.time-left', this).text(seconds_remaining);
}
else {
$(this).hide();
}
}
});
}, 1000);
});
You could also cancel the interval function when there is nothing left to expire.
Your problem seems to be that this doesn't refer to the current DOM element (from the each), but to window - from setTimeout.
Apart from that, you have an unnecessary domReady wrapper, forgot the # on your id selector, should use cached references and never rely on the timing of setInterval, which can be quite drifting. Use this:
$(document).ready(function(){
$(".product").each(function(){
var end = new Date(/* from something */),
toUpdate = $(".time_left", this);
prod = $(this);
countDown();
function countdown() {
var cur = new Date(),
left = end - cur;
if (left <= 0) {
prod.remove(); // or .hide() or whatever
return;
}
var sec = Math.ceil(left / 1000);
toUpdate.text(sec + " seconds remaining!"); // don't use .html()
setTimeout(countdown, left % 1000);
}
});
});