选项卡处于非活动状态时倒数计时器“延迟”?

Ada*_*ner 4 javascript css animation countdown gsap

试图构建一个非常简单的 Javascript 倒计时。但是,只要选项卡处于非活动状态,倒计时就会开始滞后并保持不正确的计数。

参见这里的 jsfiddle 例如:https ://jsfiddle.net/gbx4ftcn/

function initTimer(t) {

  var self = this,
    timerEl = document.querySelector('.timer'),
    minutesGroupEl = timerEl.querySelector('.minutes-group'),
    secondsGroupEl = timerEl.querySelector('.seconds-group'),

    minutesGroup = {
      firstNum: minutesGroupEl.querySelector('.first'),
      secondNum: minutesGroupEl.querySelector('.second')
    },

    secondsGroup = {
      firstNum: secondsGroupEl.querySelector('.first'),
      secondNum: secondsGroupEl.querySelector('.second')
    };

  var time = {
    min: t.split(':')[0],
    sec: t.split(':')[1]
  };

  var timeNumbers;

  function updateTimer() {

    var timestr;
    var date = new Date();

    date.setHours(0);
    date.setMinutes(time.min);
    date.setSeconds(time.sec);

    var newDate = new Date(date.valueOf() - 1000);
    var temp = newDate.toTimeString().split(" ");
    var tempsplit = temp[0].split(':');

    time.min = tempsplit[1];
    time.sec = tempsplit[2];

    timestr = time.min + time.sec;
    timeNumbers = timestr.split('');
    updateTimerDisplay(timeNumbers);

    if (timestr === '0000')
      countdownFinished();

    if (timestr != '0000')
      setTimeout(updateTimer, 1000);

  }

  function animateNum(group, arrayValue) {

    TweenMax.killTweensOf(group.querySelector('.number-grp-wrp'));
    TweenMax.to(group.querySelector('.number-grp-wrp'), 1, {
      y: -group.querySelector('.num-' + arrayValue).offsetTop
    });

  }

  setTimeout(updateTimer, 1000);

}
Run Code Online (Sandbox Code Playgroud)

我不确定问题出在动画上,还是出在 JS 代码本身上。

澄清一下:我希望在选项卡处于非活动状态时继续倒计时,或者在选项卡重新聚焦时“赶上自己”。

我知道,setTimeout并且setInterval能和未激活的标签引起的问题,但我不完全知道如何解决这个问题。

任何帮助将非常感激!

Jon*_*llo 5

为此,您可以使用HTML5 Visibility API来检测浏览器选项卡是否处于活动状态。并为浏览器窗口的焦点和模糊使用事件处理程序的常规绑定。

基本上pause(),当您模糊选项卡时,您会看到时间线,然后play()当您重新聚焦选项卡时。这在行动的例子:

http://codepen.io/jonathan/pen/sxgJl

// 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";
}

// If the page is hidden, pause the video;
// if the page is shown, play the video
function handleVisibilityChange() {
   if (document[hidden]) {
      tl.pause();
   } else {
      tl.play();
   }
}

// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") {
   // do nothing or throw error via alert()
   alert("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
   // Handle page visibility change 
   // Pause timeline  
   tl.pause();
}
Run Code Online (Sandbox Code Playgroud)

HTML5 可见性文档:

https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API

关于 GreenSock 论坛主题:

http://forums.greensock.com/topic/9059-cross-browser-to-detect-tab-or-window-is-active-so-animations-stay-in-sync-using-html5-visibility-api/

同样在 GSAP 中,setTimeout() 的等效项是 delayedCall()

提供一种在设定的时间(或帧)后调用函数的简单方法。您也可以选择将任意数量的参数传递给函数。

GSAP 延迟调用():http ://greensock.com/docs/#/HTML5/GSAP/TweenMax/delayedCall/

//calls myFunction after 1 second and passes 2 parameters:
TweenMax.delayedCall(1, myFunction, ["param1", "param2"]);

function myFunction(param1, param2) {
    //do stuff
}
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助!