文章目录
- 效果
- 过程
- 日历与获取时间
- 居中
- 背景与字
- 计时器
- 清空计时器
- 代码
- HTML
- CSS
- JS
其他demo
效果
效果预览:倒计时器 可选择时间 (codepen.io)
参考:
Simple Clock/Countdown timer (codepen.io)
前端页面实现倒计时效果的几种方法_前端倒计时__Boboy的博客-CSDN博客
过程
日历与获取时间
这个是<input type="date">
想要获取时间:这样就可以把点击的时间传入
<input class="date" id="date" type="date" value="" onchange="timeChange(this.value)">
居中
想让body的内容上下居中,设置了flex
并justify-content: center;
时没有效果。这是因为body没有高度,它的高度是由内容撑开的,无法上下居中。 想要解决这个问题,需要设置
height: 100vh;
使得body占满整个窗口,此时就有内容的上下居中效果了。
左右居中同理(width:100vw
)。
背景与字
背景颜色:
background-image: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
背景是一种绿色,字体颜色color是白色(或偏白色的浅绿色),影子text-shadow的阴影颜色是深绿色。颜色很和谐。
计时器
我们获取选择的时间后,就可以计算选择的时间与当前时间的差值,然后需要写一个计时器setTimeOut
,每一秒调用一次自己 ,这样才会有秒数动态减少的效果。
timer = setTimeout(function () {timeChange(date)}, 1000);
我们令每次调用timeChange
都输出当前时间:很显然,每次都要调用一次。
注意,这里不能写:
timer = setTimeout(timeChange(date), 1000);
这是复杂度为2n的递归调用,会调用很多次函数。第1秒的时候调用1次,第2秒时调用2次(原本的和新递归出来的),第3秒调用4次…会爆栈。
清空计时器
当选择新的时间时,要把之前的计时器清除,否则会出现两个计时器同时工作的情况:
if(timer!=='') clearTimeout(timer);
代码
HTML
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>倒计时器</title><link rel="stylesheet" href="style.css">
</head><body><div class="main"><div class="title"><div class="text">请输入未来的时间</div><input class="date" id="date" type="date" value="" onchange="timeChange(this.value)"></div><div class="container"><div class="item"><p class="time">D</p><p class="text">DAYS</p></div><div class="item"><p class="time">O</p><p class="text">HOURS</p></div><div class="item"><p class="time">N</p><p class="text">MINUTES</p></div><div class="item"><p class="time">E</p><p class="text">SECONDS</p></div></div></div></body></html><script src="index.js"></script>
CSS
body {background-image: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
}.main {display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100vh;width: 100vw;}.title {text-align: center;
}.title .text {font-size: 50px;color: #dbfff69c;text-shadow: 0 0 10px #009974;margin: 40px 0;
}.title .date {width: 100px;text-align: center;margin-bottom: 35px;background-color: #beffef;border-radius: 10px;border: 1px solid #beffef;padding: 5px;}.container {display: flex;margin-left: 90px;
}.container .item {margin-right: 70px;text-align: center;
}.container .item .time {font-size: 36px;font-weight: 300;
}.container .item .text {font-size: 14px;font-weight: 400;border-top: 1px solid #131313;padding-top: 10px;margin-top: -14px;
}
JS
let timer=''function timeChange(date) {console.log(date)// 每次选择了新时间要关闭之前的定时器if(timer!=='') clearTimeout(timer);let now = new Date().getTime();let future = new Date(date).getTime()let distance = future - nowconst time = document.getElementsByClassName('time')const len = time.length;if (distance <= 0) {let arr = 'DONE'for (let i = 0; i < len; i++) {time[i].innerHTML = arr[i];}timer=''return;}let days = Math.floor(distance / (1000 * 60 * 60 * 24));distance -= days * (1000 * 60 * 60 * 24);let hours = Math.floor(distance / (1000 * 60 * 60));distance -= hours * (1000 * 60 * 60);let minutes = Math.floor(distance / (1000 * 60));distance -= minutes * (1000 * 60);let seconds = Math.floor(distance / 1000);let arr = [days, hours, minutes, seconds];for (let i = 0; i < len; i++) {time[i].innerHTML = arr[i];}timer = setTimeout(function () {timeChange(date)}, 1000);
}