文章目录
- 效果
- 过程
- 日历与获取时间
- 居中
- 背景与字
- 计时器
- 清空计时器
- 代码
- 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 - now
const 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);
}