上下文:对于自助服务终端应用程序,出于偏离主题的原因(参见here),我不依赖操作系统屏幕保护程序,而是在 JS 中实现屏幕保护程序:黑色模态层(全宽、全宽)用户不活动 5 分钟后,会出现带有徽标的高度)。
这是我使用的,它有效(这里延迟是2秒):
var screensaver_task = null;
var start_screensaver = () => {
document.querySelector(".screensaver-layout").classList.add("hidden");
if (screensaver_task) {
clearTimeout(screensaver_task);
screensaver_task = null;
}
screensaver_task = setTimeout(() => {
document.querySelector(".screensaver-layout").classList.remove("hidden");
}, 2 * 1000);
}
document.addEventListener("mousemove", start_screensaver);
document.addEventListener("click", start_screensaver);
start_screensaver();
.screensaver-layout { background: black; z-index: 1000; position: fixed; top: 0; left: 0; width: 100%; height: 100%; }
.hidden { display: none; }
Mouse move here and wait 2 seconds...
<div class="screensaver-layout hidden"></div>
问题:以这种方式,即对于每个
clearTimeout
(这可能在几秒钟内发生数百次),对于setTimeout
和mousemove
是否不是最佳(性能方面):是否有更好的方法如何处理这个屏幕保护程序触发?
我会在
mousemove
处理程序中做尽可能少的工作。
因为我希望你不需要屏幕保护程序在最后一次移动后恰好2秒(或其他什么)启动,所以我只会一直缓慢地运行
interval
来检查自此以来是否有足够的时间最后一次鼠标移动,如下所示:
let lastMouseTime = 0;
let screensaverRunning = false;
function updateRunning(flag) {
screensaverRunning = flag;
document
.querySelector(".screensaver-layout")
.classList.toggle("hidden", !screensaverRunning);
}
setInterval(() => {
if (!lastMouseTime) return;
if (!screensaverRunning) {
if (+new Date() - lastMouseTime >= 2000) {
updateRunning(true);
}
}
}, 1000);
document.addEventListener("mousemove", () => {
lastMouseTime = +new Date();
if (screensaverRunning) {
updateRunning(false);
}
});
.screensaver-layout {
background: rgba(0, 255, 0, 0.5);
z-index: 1000;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.hidden {
display: none;
}
Mouse move here and wait approximately 2 seconds...
<div class="screensaver-layout hidden"></div>