【发布时间】:2021-05-27 04:11:06
【问题描述】:
我想根据浏览器中是否处于活动状态来更新页面上的数据。这仅适用于针对 document.hasFocus() 的 if 查询。
但我现在还想要的是,当焦点回到页面时,会立即或至少在 5 秒内发生更新,然后通常在 30 秒后再次发生。
我现在的想法是在区间内改变区间时间。但是,我无法做到这一点。
useEffect(() => {
const statusRefreshInterval = setInterval(() => {
if (document.hasFocus()) {
console.log("hasFocus:", new Date().toLocaleTimeString());
setInterval(statusRefreshInterval, 30000);
} else {
console.log("hasNoFocus:", new Date().toLocaleTimeString());
setInterval(statusRefreshInterval, 5000);
}
}, 30000);
return () => clearInterval(statusRefreshInterval);
}, []);
编辑: 这样,我就满足了我的所有要求:
var lastUpdate = useRef(); // needed to use variables inside useEffect
const allowedUpdatesAfterSec = 300;
useEffect(() => {
// initial update
lastUpdate.current = Date.now() / 1000;
// update when website gets focus again
window.addEventListener("focus", function () {
if (Date.now() / 1000 - lastUpdate.current > allowedUpdatesAfterSec) {
console.log("EventListenerUpdate:", new Date().toLocaleTimeString());
lastUpdate.current = Date.now() / 1000;
}
});
// update every allowedUpdatesAfterSec when website is active
const updateRefreshInterval = setInterval(() => {
if (Date.now() / 1000 - lastUpdate.current > allowedUpdatesAfterSec) {
if (document.hasFocus()) {
console.log("IntervalUpdate:", new Date().toLocaleTimeString());
lastUpdate.current = Date.now() / 1000;
}
}
}, 60000);
return () => clearInterval(updateRefreshInterval);
}, []);
我会考虑改用 setTimeout 而不是 setInterval。
【问题讨论】:
-
您的意思是用新值更改间隔“内”或下一个间隔之前的间隔?您对每个都有硬编码值,但也许一个参数是您想要/需要的? stackoverflow.com/q/109086/125981
-
“焦点回到页面”焦点事件没有冒泡,所以也许你需要为那个事件添加一个事件处理程序然后处理developer.mozilla.org/en-US/docs/Web/API/Element/focus_event
-
我会考虑使用 setTimeout 而不是冒着堆积 setIntervals 的风险——只是为了安全起见。
标签: javascript reactjs setinterval