setInterval()没有被清除?

时间:2015-11-09 06:58:48

标签: javascript html5 canvas

我正在尝试使用页面可见性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都不会清除,并且绘图加速,好像有多个在它上面调用setIntervals。如果您离开并多次返回选项卡,则动画会加速到荒谬的比例。

这里发生了什么?为什么在handleVisibilityChange函数中没有清除间隔?

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

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

2 个答案:

答案 0 :(得分:2)

<强>更新 在评论中说。

我犯了一个错误,而requestAnimationFrame不会让计算机独自保持清醒状态。但是,如果您正在播放视频,则可以使用requestAnimationFrame来观看视频。虽然是让视频保持清醒的视频。

术语&#34; 焦点&#34;可能不正确,但有人建议只在&#34; 可见&#34;是不准确的,因为当你在窗口上放置另一个窗口时会一直触发,如果窗口最大化则会发生事件,或者滚动你正在看不到的动画。 requestAnimationFrame也不必显示任何内容,并且调用不知道你在回调体中做了什么,你可能只是在计算帧数。

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

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

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

答案 1 :(得分:0)

试试这个: 移动&#34; var drawPic;&#34;声明在函数之外。如果其他人需要在将来进行测试,则包括其他代码(为了完整起见)。

// 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);

}