setInterval()未被清除

setInterval() Not being cleared?

本文关键字:清除 setInterval      更新时间:2023-09-26

当用户将焦点切换到另一个浏览器选项卡时,我正试图使用页面可见性api来暂停画布动画:

var hidden, visibilityChange; 
if (typeof document.hidden !== "undefined") { // Opera 12.10 & Firefox 18 & later support
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} 
function drawStuff () {
  //draws & rotates stuff on canvas
}
function handleVisibilityChange() {
  if (document[hidden]) {
    clearInterval(drawPic);
  } else {
    var drawPic = setInterval(drawStuff, 60);
  }
}
handleVisibilityChange();
document.addEventListener("visibilitychange", handleVisibilityChange, false);

我希望动画完全恢复到它停止的位置,但由于某种原因,每次我离开选项卡并返回页面时,setInterval都不会清除,绘图速度也会加快,就好像有多个setInterval被调用一样。如果你多次离开并返回选项卡,动画速度会达到荒谬的比例。

这是怎么回事?为什么handleVisibilityChange函数中没有清除间隔?

编辑:移动var声明修复了它,谢谢。

编辑2:添加在文档的代码中[隐藏]以供将来参考(如Suing&Tushar所述)。

更新在淫荡的评论中。

我犯了一个错误,requestAnimationFrame无法让计算机保持清醒。如果您正在播放视频,并且可以使用requestAnimationFrame查看视频,则会出现这种情况。尽管是视频让电脑保持清醒。

此外,术语"焦点"可能不正确,尽管有人建议它只在"visible"不准确时更新,因为当你将另一个窗口放在窗口上时,它会一直亮起,如果该窗口最大化,则会发生事件,或者将你正在设置的动画滚动到视图之外。requestAnimationFrame也不必显示任何内容,并且调用不知道您在回调主体中做了什么,您可能只是在计算帧。

目前,我将使用术语"页面焦点",这意味着页面是浏览器窗口的显示选项卡,它不必具有系统焦点,但如果有人有更准确的描述,请说。

使用window.requestAnimationFrame(functionName);,它在您失去页面焦点时停止调用,然后在您重新获得页面焦点时重新启动。提供浏览器支持的最大可见帧速率(1/60秒的间隔),并将动画与浏览器的布局和渲染器同步。

有关如何使用和兼容性的详细信息,请参阅MDN requestAnimationFrame。

试试这个:将"var drawPic;"声明移到函数之外。如果其他人将来需要测试,则包括其他代码(为了完整性)。

// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange; 
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support 
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
  hidden = "mozHidden";
  visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
  hidden = "msHidden";
  visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
}
function drawStuff () {
  //draws & rotates stuff on canvas
}
var drawPic;
function handleVisibilityChange() {
  if (document[hidden]) {
    clearInterval(drawPic);
  } else {
    drawPic = setInterval(drawStuff, 60);
  }
}
handleVisibilityChange();
// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || 
  typeof document[hidden] === "undefined") {
  alert("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
  // Handle page visibility change   
  document.addEventListener(visibilityChange, handleVisibilityChange, false);
}