从计时器失效到判断页面可见性
2023-12-16 04:46:47
1,问题 - 计时器失效
问题复现:移动端必现,pc 端和浏览器版本有关(公司电脑必现,家里的没有复现)。
通过 setTimeout
或 setInterval
实现的倒计时,会在页面隐藏后,实测会延缓计时或经过15s 左右会停止计时,导致计时不准确!直到页面再次激活。
2,解决 - 页面可见性判断
可以通过判断页面可见性,计算出经过的隐藏时间来重置倒计时的时间点。
1,页面可见性
无论使用 pc 还是移动端,都会有当前页面被隐藏的情况:
- 切换 tab 页
- 浏览器最小化
- 切换到其他应用
- 点击链接跳转到其他页面
2,visibilitychange
document.addEventListener("visibilitychange", () => {
// 页面可见
if (document.visibilityState === "visible") {
console.log("visible");
} else {
console.log("hidden");
}
});
举例:计算隐藏时间
<body>
<div id="box">100</div>
<script>
const box = document.getElementById("box");
// 初始时间
let count = 100;
const inerval = setInterval(() => {
if (count <= 0) {
box.innerHTML = "倒计时结束";
clearInterval(inerval);
document.removeEventListener("visibilitychange", visibilitychange);
return;
}
box.innerHTML = count--;
}, 1000);
let startTime2Hidden = 0; // 页面隐藏瞬间的时间
let count2Hidden = 0; // 记录页面隐藏瞬间的 count 值
document.addEventListener("visibilitychange", visibilitychange);
function visibilitychange() {
if (document.visibilityState === "visible") {
const minus = parseInt((new Date().getTime() - startTime2Hidden) / 1000);
count = count2Hidden - minus; // 正确经过的时间
} else {
startTime2Hidden = new Date().getTime();
count2Hidden = count;
}
}
</script>
visibilitychange 的问题:在 safari 浏览器下,这个事件不总是触发,比较怪异。
3,终极解决方案 - lifecycle
谷歌实验室开源项目,兼容性很好。
使用举例:
<script src="./lifecycle.es5.js"></script>
<script>
lifecycle.addEventListener("statechange", function (event) {
console.log(event.oldState, event.newState);
if (event.oldState == "passive" && event.newState == "hidden") {
console.log("hidden");
} else if (event.oldState == "hidden" && event.newState == "passive") {
console.log("visibile");
}
});
</script>
3,精准计时
无论使用哪种解决方案,倒计时都不是准确的,因为用户可能会修改本地时间,况且 js 计时本身就不精准。
要实现精准计时,还得靠后端接口返回正确的时间(后端也会做校验)。
以上面这个问题来说,另一种解决方案:在页面激活时再次请求一次倒计时相关的接口,前端重置倒计时时间点。
以上。
文章来源:https://blog.csdn.net/qq_40147756/article/details/135026571
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!