我想根据页面在浏览器中是否处于活动状态来更新页面上的数据。这只适用于针对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。
您可以使用动态时间从setTimeout
回调递归调用setTimeout
,例如-
let timeToCall = 1000
let seconds = Date.now()/1000
function dynamicTimeoutFunction() {
console.log(`I was called after ${Date.now()/1000 - seconds} seconds`)
timeToCall += 1000
setTimeout(dynamicTimeoutFunction, timeToCall)
}
setTimeout(dynamicTimeoutFunction, timeToCall)
您只是通过这种方式创建了更多的间隔,因为您是从setInterval中调用setInterval的。我只想把setInterval改为setTimeout。
useEffect(() => {
const statusRefreshInterval = setTimeout(() => {
if (document.hasFocus()) {
console.log("hasFocus:", new Date().toLocaleTimeString());
setTimeout(statusRefreshInterval, 30000);
} else {
console.log("hasNoFocus:", new Date().toLocaleTimeString());
setTimeout(statusRefreshInterval, 5000);
}
}, 30000);
return () => clearTimeout(statusRefreshInterval);
}, []);
通过这种方式,您可以为下一次通话设置新的时间。