我正在尝试构建一个从一个日期到下一个日期的倒计时时钟。一个例子是倒数万圣节到感恩节。倒数到零时,我希望计数器重新启动并倒数到下一个假期。
我尝试过分离事件,并以不同的方式标记事件以独立地定位它们。任何想法都很棒,这让我陷入了困境。
<div class="container">
<p id="timer">
<span id="timer-days"></span>
<span id="timer-hours"></span>
<span id="timer-minutes"></span>
<span id="timer-seconds"></span>
</p>
</div>
<script>
var holidazeEnd=new Date("Jun, 9 2019 18:19:00").getTime();
var holidazeEnd1=new Date("Jun, 9 2019 18:20:00").getTime();
var timer= setInterval(function(){
let now=new Date().getTime();
let t=holidazeEnd - now;
if (t >= 0)
{
let days = Math.floor(t / (1000 * 60 * 60 * 24));
let hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let mins = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
let secs = Math.floor((t % (1000 * 60)) / 1000);
document.getElementById("timer-days").innerHTML=days+"<span class= 'label'> Days</span>";
document.getElementById("timer-hours").innerHTML=("0"+hours).slice(-2)+"<span class= 'label'> Hours</span>";
document.getElementById("timer-minutes").innerHTML=("0"+mins).slice(-2)+"<span class= 'label'> Minutes</span>";
document.getElementById("timer-seconds").innerHTML=("0"+secs).slice(-2)+"<span class= 'label'> Seconds</span>";
}
else{
document.getElementById("timer").innerHtml=("Happy Independence Day!");}
},1000)
//---------------------------------------------//
var timer1= setInterval(function(){
let now=new Date().getTime();
let t=holidazeEnd1 - now;
if (t >= 0) {
let days1 = Math.floor(t / (1000 * 60 * 60 * 24));
let hours1 = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let mins1 = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
let secs1 = Math.floor((t % (1000 * 60)) / 1000);
document.getElementById("timer-days").innerHTML=days1+"<span class= 'label'> Days</span>";
document.getElementById("timer-hours").innerHTML=("0"+hours1).slice(-2)+"<span class= 'label'> Hours</span>";
document.getElementById("timer-minutes").innerHTML=("0"+mins1).slice(-2)+"<span class= 'label'> Minutes</span>";
document.getElementById("timer-seconds").innerHTML=("0"+secs1).slice(-2)+"<span class= 'label'> Seconds</span>";
}
else
document.getElementById("timer1").innerHtml="Merry Xmas!";}
,1000);
countdown(holidazeEnd,timer);
countdown(holidazeEnd1,timer1)
答案 0 :(得分:1)
要使用单个setInterval和一系列假日吗?
const holidays = [
{
running: "Independence Day",
complete: "Happy Independence Day!",
time: "July 4 2019"
},
{
running: "Christmas",
complete: "Merry Xmas!",
time: "Dec 10 2019"
}
];
我们需要知道要跟踪的下一个假期:
//Get the next holiday index
const nextHolidayIndex = () => holidays.reduce((prevResult,current, i) => {
const timeDif = Date.parse(current.time) - Date.now();
if(timeDif < 0)
return prevResult;
if(prevResult.index == -1 || timeDif < prevResult.diff) return {
index : i,
diff: timeDif
};
return prevResult;
}, {index : -1, diff: 0}).index;
剩余时间,与您一样:
//Get time remaining for a given time
const getTimeRemaining = (timeTime) =>{
const t = Date.parse(timeTime) - Date.now();
const seconds = Math.floor( (t/1000) % 60 );
const minutes = Math.floor( (t/1000/60) % 60 );
const hours = Math.floor( (t/(1000*60*60)) % 24 );
const days = Math.floor( t/(1000*60*60*24) );
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
我们需要初始化组件:
const initializeClock = (id, nextHoliday) => {
const clock = document.getElementById(id);
const message = clock.querySelector('.message');
const daysSpan = clock.querySelector('.days');
const hoursSpan = clock.querySelector('.hours');
const minutesSpan = clock.querySelector('.minutes');
const secondsSpan = clock.querySelector('.seconds');
let interval
function updateClock() {
const t = getTimeRemaining(nextHoliday.time);
daysSpan.innerHTML = t.days.toString();
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(interval);
message.innerHTML = nextHoliday.complete
}
}
message.innerHTML = `${nextHoliday.running}`
updateClock();
interval = setInterval(updateClock, 1000);
}
html怎么样?
<div id="timer">
<h1 class="message"></h1>
<div class="countdown">
<div>
<span class="days"></span>
<div class="smalltext">Days</div>
</div>
<div>
<span class="hours"></span>
<div class="smalltext">Hours</div>
</div>
<div>
<span class="minutes"></span>
<div class="smalltext">Minutes</div>
</div>
<div>
<span class="seconds"></span>
<div class="smalltext">Seconds</div>
</div>
</div>
</div>
在其中添加一些视觉效果
#timer{
text-align: center;
background: #efefef;
font-family: sans-serif;
font-weight: 100;
display: inline-flex;
flex-direction: column;
padding: 24px;
}
h1{
color: #969696;
font-weight: 100;
font-size: 40px;
margin: 0 0 15px 0;
}
#timer .countdown{
color: #fff;
display: inline-block;
font-weight: 100;
text-align: center;
font-size: 30px;
}
#timer .countdown > div{
padding: 10px;
border-radius: 3px;
background: #6f7b75;
display: inline-block;
}
#timer .countdown div > span{
padding: 15px;
border-radius: 3px;
background: #03A9F4;
display: inline-block;
}
.smalltext{
padding-top: 5px;
font-size: 16px;
}
然后我们只运行代码:
const next = nextHolidayIndex()
if(next != -1){
initializeClock('timer', holidays[next]);
}
您在这里:)
const holidays = [
{
running: "Independence Day",
complete: "Happy Independence Day!",
time: "July 4 2019"
},
{
running: "Christmas",
complete: "Merry Xmas!",
time: "Dec 10 2019"
}
];
//Get the next holiday index
const nextHolidayIndex = () => holidays.reduce((prevResult,current, i) => {
const timeDif = Date.parse(current.time) - Date.now();
if(timeDif < 0)
return prevResult;
if(prevResult.index == -1 || timeDif < prevResult.diff) return {
index : i,
diff: timeDif
};
return prevResult;
}, {index : -1, diff: 0}).index;
//Get time remaining for a given time
const getTimeRemaining = (timeTime) =>{
const t = Date.parse(timeTime) - Date.now();
const seconds = Math.floor( (t/1000) % 60 );
const minutes = Math.floor( (t/1000/60) % 60 );
const hours = Math.floor( (t/(1000*60*60)) % 24 );
const days = Math.floor( t/(1000*60*60*24) );
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
const initializeClock = (id, nextHoliday) => {
const clock = document.getElementById(id);
const message = clock.querySelector('.message');
const daysSpan = clock.querySelector('.days');
const hoursSpan = clock.querySelector('.hours');
const minutesSpan = clock.querySelector('.minutes');
const secondsSpan = clock.querySelector('.seconds');
let interval
function updateClock() {
const t = getTimeRemaining(nextHoliday.time);
daysSpan.innerHTML = t.days.toString();
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(interval);
message.innerHTML = nextHoliday.complete
startNext()
}
}
message.innerHTML = `${nextHoliday.running}`
updateClock();
interval = setInterval(updateClock, 1000);
}
const startNext = () => {
const next = nextHolidayIndex()
if(next != -1){
initializeClock('timer', holidays[next]);
}
}
startNext()
#timer{
text-align: center;
background: #efefef;
font-family: sans-serif;
font-weight: 100;
display: inline-flex;
flex-direction: column;
padding: 24px;
}
h1{
color: #969696;
font-weight: 100;
font-size: 40px;
margin: 0 0 15px 0;
}
#timer .countdown{
color: #fff;
display: inline-block;
font-weight: 100;
text-align: center;
font-size: 30px;
}
#timer .countdown > div{
padding: 10px;
border-radius: 3px;
background: #6f7b75;
display: inline-block;
}
#timer .countdown div > span{
padding: 15px;
border-radius: 3px;
background: #03A9F4;
display: inline-block;
}
.smalltext{
padding-top: 5px;
font-size: 16px;
}
<div id="timer">
<h1 class="message"></h1>
<div class="countdown">
<div>
<span class="days"></span>
<div class="smalltext">Days</div>
</div>
<div>
<span class="hours"></span>
<div class="smalltext">Hours</div>
</div>
<div>
<span class="minutes"></span>
<div class="smalltext">Minutes</div>
</div>
<div>
<span class="seconds"></span>
<div class="smalltext">Seconds</div>
</div>
</div>
</div>
为了重新启动计数器,我们需要刷新页面。如果您不想要它,那么请忽略该消息,而只需在前一个到达0之后初始化下一个即可。
const initializeClock = (id, nextHoliday) => {
//...
if (t.total <= 0) {
clearInterval(interval);
startNext()
}
//...
}
const startNext = () => {
const next = nextHolidayIndex()
if(next != -1){
initializeClock('timer', holidays[next]);
}
}
startNext()
答案 1 :(得分:0)
我认为这个例子解决了这个问题:
-您可以添加任意多个日期,
-调整演示文稿的结束日期,然后再进行下一个倒计时。
出于美观原因,我进行了一些更改...
// Set all the dates you want (no order needed)
const holidays = [
{ dat: 'July, 3 YYYY 23:59:59', end: 'July, 4 YYYY 23:59:59', msg:'Happy Independence Day!', bef:'Independence Day', Bcolor : '#39CCCC' }
, { dat: 'Dec, 24 YYYY 23:59:59', end: 'Dec, 26 YYYY 12:00:00', msg:'Merry Xmas!', bef:'Xmas', Bcolor : '#2ECC40' }
, { dat: 'Oct, 31 YYYY 17:59:59', end: 'Nov, 1 YYYY 06:00:00', msg:'Happy Halloween!', bef:'Halloween', Bcolor : '#F012BE' }
, { dat: 'Dec, 31 YYYY 23:59:59', end: 'Jan, 1 Y+1Y 01:00:00', msg:'Happy New Year!', bef:'New Year', Bcolor : '#FFDC00' }
];
// please note the use of 'YYYY' stand for 'any Year' and 'Y+1Y' stand fort 'any Following Year' for events repeating each year.
// Real year values are ok but old events will be ignored
// The color is here for example, you can disable it or change the idea by placing a picture in the background,
// and do the same countdown for each species
// Ready for everything:
const BODY_color = '#554a63' // standard Color of Background
, timer_on = document.querySelector('#timer-on')
, timer_off = document.querySelector('#timer-off')
, curDT = document.getElementById('currentDateTime')
, tCountDown = document.querySelectorAll('#countdown div span')
, xDays = 0
, xHours = 2
, xMins = 4
, xSecs = 6
, t_msg = document.querySelector('#timer-on h2')
, H_message = document.querySelector('#timer-off h1')
, one_Sec = 1000
, one_Min = one_Sec * 60
, one_Hour = one_Min * 60
, one_Day = one_Hour * 24
, Option_DT = { weekday: 'long', month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit'}
, Intl_F_DT = new Intl.DateTimeFormat('en-US', Option_DT )
;
/* Search function to set the countDown target
do : set interface to correct closest countdown
even if it is during a period before ending event
return : (js object )
start : time target of event
ending : time target of event ending
complete : Boolean value (set to false) according to the countdown is not completed
Bcolor : paint color value for background during ending period
*/
function SetNextHolidayTarget()
{
let now = new Date()
, nowTime = now.getTime()
, thisYear = now.getFullYear()
, closest = one_Day *365 /// start with big closest date
, target = null
;
// default display
timer_on.classList.remove('noDisplay')
timer_off.classList.add('noDisplay')
document.body.style.backgroundColor = BODY_color;
holidays.forEach(H=> // search loop for the closest date in 'holidays'
{
let s_date = H.dat.replace('YYYY', thisYear ) // change 'YYYY' string to current year value
, e_date = H.end.replace('YYYY', thisYear ).replace('Y+1Y', (thisYear +1) )
, t_date = new Date(s_date) // target date
, z_date = new Date(e_date) // target date ending
;
if ( t_date < now && z_date < now ) // if target date and ending are before today, this set them for next year
{
s_date = H.dat.replace('YYYY', (thisYear +1))
e_date = H.end.replace('YYYY', (thisYear +1)).replace('Y+1Y', (thisYear +2) )
t_date = new Date(s_date)
z_date = new Date(e_date)
}
let t_datesDiff = t_date.getTime() - nowTime
, z_datesDiff = z_date.getTime() - nowTime
if ( closest > t_datesDiff && t_datesDiff > 0 ) // if it is closer than the dates already seen
{
closest = t_datesDiff
t_msg.textContent = H.bef
H_message.textContent = H.msg
target = { start: t_date.getTime(), ending: z_date.getTime(), complete: false, Bcolor: H.Bcolor }
}
if ( closest > z_datesDiff && z_datesDiff > 0 ) // case of inside countdown period
{
closest = z_datesDiff
t_msg.textContent = H.bef
H_message.textContent = H.msg
target = { start: z_date.getTime(), ending: z_date.getTime(), complete: true, Bcolor: H.Bcolor }
}
})
if ( target.complete ) // if inside countdown period
{
timer_on.classList.add('noDisplay')
timer_off.classList.remove('noDisplay')
document.body.style.backgroundColor = target.Bcolor;
}
return target
}
// **** INIT ****
var holidazeEnd = SetNextHolidayTarget()
// first TEST to prove -------------------------------------------------------------------
if (true) // (set to false to remove this test)
{
let now = new Date()
, start = new Date()
, ending = new Date()
;
// default display
timer_on.classList.remove('noDisplay')
timer_off.classList.add('noDisplay')
document.body.style.backgroundColor = BODY_color;
start.setTime(now.getTime() + (one_Sec *20) );
ending.setTime(start.getTime() + (one_Sec *15) );
t_msg.textContent = 'Test to 20s'
H_message.textContent = 'happy test ! (15s)'
holidazeEnd = { start , ending , complete: false, Bcolor: 'orange' }
} // =====================================================================================
// TIMER Interval //
// - - - - - - - - //
var timerInterval = setInterval(function ()
{
let now = new Date()
, t = holidazeEnd.start - now.getTime()
;
curDT.textContent = Intl_F_DT.format(now) // show date time upper right
if (t >= 0 )
{
if (!holidazeEnd.complete)
{
tCountDown[xDays].textContent = Math.floor(t / one_Day);
tCountDown[xHours].textContent = ('0' + Math.floor((t % one_Day) / one_Hour)).slice(-2);
tCountDown[xMins].textContent = ('0' + Math.floor((t % one_Hour) / one_Min)).slice(-2);
tCountDown[xSecs].textContent = ('0' + Math.floor((t % one_Min) / one_Sec)).slice(-2);
}
// else { nothing to do }
}
else // elapsed time !
{
if ( holidazeEnd.complete ) // elapsed time of ' holiday ' message
{
holidazeEnd = SetNextHolidayTarget() // searching the next one in the ' holidays ' list
}
else // show ' holiday ' message
{
timer_on.classList.add('noDisplay')
timer_off.classList.remove('noDisplay')
holidazeEnd.complete = true;
holidazeEnd.start = holidazeEnd.ending
document.body.style.backgroundColor = holidazeEnd.Bcolor
}
}
}, 1000);
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
background-color: #554a63;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
#currentDateTime {
text-align: right;
padding: .2em 1em 0 0;
color: white;
font-weight: lighter;
font-stretch: expanded
}
.noDisplay {
display:none !important
}
.timer{
position: absolute;
top: 50%;
left: 0;
display: block;
width: 100%;
transform: translateY(-50%);
}
.timer h1 {
text-align: center;
font-size: 4em;
font-weight: bold;
color: white;
background-color: rgba(96, 87, 151, 0.315);
padding: .8em 0;
}
.timer h2 {
text-align: center;
padding: .3em 0;
}
#countdown {
display: table;
margin: 0 auto;
padding: 1em 0;
background-color: rgba(96, 87, 151, 0.315);
min-width: 26em;
}
#countdown div {
display: block;
float: left;
height: 5em;
width: 6em;
border-right: 1px solid grey;
}
#countdown div:first-child {
width: 8em;
}
#countdown div:last-child {
border-right: none;
}
#countdown div span {
display: inline-block;
width: 100%;
text-align: center;
color: white
}
#countdown div span:first-child {
font-size: 3em;
}
#countdown div span:last-child {
font-size: .8em;
padding: 1em .2em;
}
<p id="currentDateTime"></p>
<div id="timer-on" class="timer">
<h2> .. </h2>
<div id="countdown">
<div><span>.</span><span>Days</span></div>
<div><span>.</span><span>Hours</span></div>
<div><span>.</span><span>Minutes</span></div>
<div><span>.</span><span>Seconds</span></div>
</div>
</div>
<div id="timer-off" class="timer noDisplay">
<h1>!</h1>
</div>