倒计时
分析:两个时间 目标时间 ,当前时间
目标时间-当前时间(计算时间差中包含多少小时,多少分钟,多少秒)
每间隔一秒钟重新获取当前时间(定时器),重算时间
核心问题:
1当前时间不可以获取客户端本地的(本地的时间客户可以肆意修改,获取服务器的时间 响应头Date)
2.获取服务器时间有 时间差问题
缩短时间差 :当ajax码为2的时候响应头信息就返回了 head请求:只要请求头
在页面不刷新的情况下,每间隔一秒,不是再从服务器获取,而是基于第一次获取的结果之上手动累加1000ms即可(如果不这样服务器会崩溃,用户得到的时间误差也会越来越大)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box">
距离抢购还剩下
<span class="text">00:00:00</span>
</div>
</body>
<!-- 两个时间 目标时间
当前时间
目标时间-当前时间(计算时间差中包含多少小时,多少分钟,多少秒)
每间隔一秒钟重新获取当前时间(定时器),重算时间
核心问题:当前时间不可以获取客户端本地的(本地的时间客户可以肆意修改,获取服务器的时间 响应头Date)
获取服务器时间有 时间差问题
缩短时间差 :当ajax码为2的时候响应头信息就返回了 head请求:只要请求头
在页面不刷新的情况下,每间隔一秒,不是再从服务器获取,而是基于第一次获取的结果之上手动累加1000ms即可
-->
<script>
let countdownModule = (function () {
let textBox = document.querySelector('.text'),
serverTime = 0,
//指定时间字符串,转为标准时间格式
targetTime = + new Date("2022 / 01 / 17 18:00:00"),
time = null
// 获取服务器时间
const queryServerTime = function () {
return new Promise(resolve => {
let xhr = new XMLHttpRequest;
xhr.open('HEAD', '/');
xhr.onreadystatechange = () => {
if (xhr.status == 200 && xhr.readyState == 2) {
//获取的为格林尼治时间-->变为北京时间
let time = xhr.getResponseHeader('date')
resolve(+new Date(time))
}
}
xhr.send(null)
})
}
// 倒计时计算
const supplyZero = function (val) {
val = +val || 0
return val < 10 ? `0${val}` : val
}
const computed = function computed() {
let diff = targetTime - serverTime,
hours,
minutes,
seconds
if (diff <= 0) {
// 到达抢购时间了
textBox.innerHTML = "00: 00: 00"
clearTimeout(time)
}
//没到时间
hours = Math.floor(diff / (1000 * 60 * 60))
diff = diff - hours * 1000 * 60 * 60
minutes = Math.floor(diff / (1000 * 60))
diff = diff - minutes * 1000 * 60
seconds = Math.floor(diff / 1000);
textBox.innerHTML = `${(supplyZero(hours))}: ${(supplyZero(minutes))}: ${(supplyZero(seconds))}`
}
return {
async init() {
serverTime = await queryServerTime()
computed()
// 设置定时器
timer = setInterval(() => {
serverTime += 1000
computed()
}, 1000)
}
}
})()
countdownModule.init()
</script>
</html>