实战分享:20分钟页面不操作,页面失效
总结
在用户长时间不操作页面的情况下,需要提示用户页面已失效并返回列表页面。如果用户进行了操作,计时器会重置。如果用户 A 在编辑页面,用户 B 尝试编辑时会被提示该页面正在被编辑。用户 A 在编辑期间,每分钟向后端发送一个请求以续租编辑权限,后端会保持该用户的编辑状态,其他用户则无法进行编辑操作。后端会根据请求返回相应的信息。
前言
故事开始于产品经理提出的需求,为了寻找解决方案,我咨询了导师。然而,团队中没有现成的解决方案,导师建议使用 web worker 来解决这个问题。于是我开始了这次挑战。
起初,我想通过 setInterval
来实现定时功能,但发现当切换浏览器标签页时,setInterval
会停止计时,因此这个方法行不通。于是我决定使用 web worker
,它可以在新的线程中进行计时,不受页面切换的影响。
正文思路
基本 Demo
首先,通过一个简单的 web worker
示例,了解它的基本实现:
<!-- editEmail.vue(主线程) -->
<template>
<div>编辑页面哦</div>
</template>
<script>
const myWorker = new Worker('/worker.js'); // 创建worker
// 向 worker.js 线程发送消息
myWorker.postMessage('Greeting from Main.js');
// 从 worker.js 接收消息
myWorker.addEventListener('message', e => {
console.log(e.data); // Greeting from Worker.js
});
</script>
worker.js
文件内容如下:
// worker.js(worker线程)
self.addEventListener('message', e => {
console.log(e.data); // Greeting from Main.js
self.postMessage('Greeting from Worker.js'); // 向主线程发送消息
});
通过以上代码实现了主线程与 worker
线程的通信。
实现续租和页面失效功能
续租请求: 每分钟向服务端发送续租请求,保持编辑状态。
页面失效提示: 在用户20分钟内无操作时,提示页面失效并返回列表页面。
worker.js
代码如下:
// worker.js(worker线程)
let timer;
self.addEventListener('message', e => {
console.log(e.data); // 主线程发送的消息
let sum = 0;
let msg;
if (e.data === "start") {
timer = setInterval(() => {
sum += 1;
msg = {
text: 'editing',
sum
}
self.postMessage(msg); // 向主线程发送消息
}, 60 * 1000); // 每分钟 sum 加 1
} else {
clearInterval(timer); // 停止计时
}
});
editEmail.vue
的代码如下:
<template>
<div>编辑页面哦</div>
<input @change="onChange" />
</template>
<script>
const myWorker = new Worker('/worker.js'); // 创建worker
myWorker.postMessage('start');
// 开启定时
const onTimeStart = () => {
myWorker.postMessage('start');
}
// 停止定时
const onTimeEnd = () => {
myWorker.postMessage('end');
}
// 重置定时
const onTime = () => {
onTimeEnd();
onTimeStart();
}
myWorker.addEventListener('message', e => {
console.log(e.data); // 接收 worker 线程发送的消息
campaignListLock(); // 发起续租请求
if (e.data.sum >= 20) { // 超过 20 分钟
onTimeEnd(); // 停止计时
if (document.visibilityState === "visible") {
message.error("页面已失效");
pageGoBack(); // 返回列表页面
}
document.addEventListener("visibilitychange", function () {
if (document.visibilityState == "visible") {
message.error("页面已失效");
pageGoBack();
}
});
}
});
// 表单操作时重置计时
const onChange = () => {
onTime();
}
</script>
切换浏览器标签页的处理
我们通过 visibilitychange
事件监听浏览器标签页的切换状态,确保用户切换回页面时正确提示页面失效。
document.addEventListener("visibilitychange", function () {
if (document.visibilityState === "visible") {
message.error("页面已失效");
}
});
最终,实现了一个完善的功能,当用户在页面停留超过20分钟或切换标签页再返回时,都会提示页面失效并返回列表页面。
结语
通过 web worker 实现了一个简单有效的页面失效功能,在用户长时间不操作时,可以及时通知用户并返回列表页面。此方案不仅能应对复杂的前端交互需求,还能提升用户体验。如果你在实际项目中遇到类似需求,不妨参考这个思路进行实现。