-
个人博客:kirk.wang/
-
解决什么问题? 使用new Date()方式实现的倒计时会受到系统时间的影响,比如修改系统时间,就可以修改倒计时的时间。
-
perfromance.now是什么?
-
在JavaScript中,perfromance.now()方法可用于检查代码的性能。您可以使用此方法检查代码的执行时间。
它返回以毫秒为单位的时间值(double类型)。返回的值表示自执行开始以来经过的时间。 用法:
let t = performance.now();
下面的代码将使您对该代码的执行方式有一个简短的了解。
范例1:
<script>
const t0 = performance.now();
for (let i = 0; i < 10; i++) {
console.log(i);
}
const t1 = performance.now();
console.log(`Call to doSomething took ${t1 - t0} milliseconds.`);
</script>
- 根据这个特性,我们可以使用performance.now 实现不受系统时间影响的倒计时
先看效果图
以下是完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="width:100vw;padding-top: 100px;">
<div>
<div style="display: flex;justify-content: center;flex-direction: column; align-items: center;">
<div class="title">倒计时1-服务器时间</div>
<div class="currentTime"></div>
<div><button class="stopBtn">stop</button>
<button class="pauseBtn">pause</button>
</div>
</div>
<br>
</br>
<div style="display: flex;justify-content: center;flex-direction: column; align-items: center;">
<div class="title">倒计时2-毫秒数倒计时</div>
<div class="currentTime2"></div>
<div><button class="stopBtn2">stop</button>
<button class="pauseBtn2">pause</button>
</div>
</div>
</div>
<script>
(async () => {
var localStartTime;
var ServeTime = await getServerTime()
var ServeEndTime = await getServerEndTime()
// 服务器当前时间
function getCurrentServeTime() {
return ServeTime + (performance.now() - localStartTime)
}
// 服务器剩余时间数
async function getTime() {
return ServeEndTime - getCurrentServeTime()
}
// 毫秒转天时分秒
function formatDuring(mss) {
var days = parseInt(mss / (1000 * 60 * 60 * 24));
var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
var seconds = (mss % (1000 * 60)) / 1000;
return days + " 天 " + hours + " 小时 " + minutes + " 分钟 " + seconds.toFixed() + " 秒 ";
}
async function getServerTime() {
localStartTime = performance.now()
return Promise.resolve(new Date("2023-06-02 12:00:00").getTime())
}
async function getServerEndTime() {
return Promise.resolve(new Date("2023-06-02 12:01:00").getTime())
}
/**
* @description: 开启定时器
* @param {*} time // 毫秒数
* @param {*} callback 没帧的回调,返回剩余毫秒数
* @return {*} { stop,pause } 返回停止和暂停函数
*/
function setTime(time, callback) {
// 开启标志符
var isProgressing = false
// 本地结束时间
let localEndTime = performance.now() + time
function next() {
// 剩余的毫秒数
residueTime = localEndTime - performance.now()
residueTime = residueTime > 0 ? residueTime : 0
if (typeof callback == 'function') {
callback(residueTime)
}
if (residueTime > 0 && !isProgressing) {
requestAnimationFrame(next)
}
}
// 停止
function stop() {
isProgressing = true
localEndTime = 0
}
// 暂停/开始
function pause() {
isProgressing = !isProgressing
if (isProgressing === false && localEndTime != 0) {
// 重新开始重置本地结束时间
localEndTime = performance.now() + time
next()
} else {
// 获得剩余的时间
time = localEndTime - performance.now()
}
}
next()
return {
stop,
pause
}
}
async function start1() {
var time = await getTime()
let { stop, pause } = setTime(time, (residueTime) => {
let currentText = formatDuring(residueTime)
let dom = document.querySelector('.currentTime')
dom.innerHTML = currentText
})
let btn = document.querySelector('.stopBtn')
btn.addEventListener('click', stop)
let btn2 = document.querySelector('.pauseBtn')
btn2.addEventListener('click', pause)
}
async function start2() {
var time = await getTime()
let { stop, pause } = setTime(time, (residueTime) => {
let currentText = formatDuring(residueTime > 0 ? residueTime : 0)
let dom = document.querySelector('.currentTime2')
dom.innerHTML = currentText
})
let btn = document.querySelector('.stopBtn2')
btn.addEventListener('click', stop)
let btn2 = document.querySelector('.pauseBtn2')
btn2.addEventListener('click', pause)
}
start1()
start2()
})()
</script>
</body>
</html>