繁体   English   中英

构建一个在用户切换选项卡时停止的面向对象的计时器

[英]Building an object-oriented timer that stops when user switch tabs

我想知道是否有更好的面向 object 的方式来创建这个计时器? (没有全局变量!)

let secondsPassed = 0;
let timerId;

function startTimer() {
  clearInterval(timerId);
  timerId = setInterval(function() {
    const seconds = twoDigits((Math.floor(secondsPassed )) % 60);
    const minutes = twoDigits(Math.floor(secondsPassed / 60) % 60);
    const hours = Math.floor(secondsPassed / 60 / 60);
    $('#timer').text(`${hours}:${minutes}:${seconds}`);
    secondsPassed++;
  }, 1000);
  
  $(window).blur(function() {
      clearInterval(timerId) // stop timer when user leaves tab
  });
  
  $(window).focus(function() {
    startTimer(); // continue timer when user comes back
  });
}

您当前的实现实际上是错误的。 每次调用startTimer时,它都会将startTimer作为新的 window 焦点事件处理程序安装,当您第二次聚焦 window 时,会导致多个启动间隔; 成倍增长。 onfocus 处理程序应该只运行timerId = setInterval(…)行 - 将它放在嵌套的帮助器 function 中以仅调用它。

这也使得不必全局声明变量。

function createTimer() {
  let secondsPassed = 0;
  let timerId;
  function resume() {
    if (timerId) return; // prevent multiple intervals running at the same time
    timerId = setInterval(() => {
      const seconds = twoDigits((Math.floor(secondsPassed )) % 60);
      const minutes = twoDigits(Math.floor(secondsPassed / 60) % 60);
      const hours = Math.floor(secondsPassed / 60 / 60);
      $('#timer').text(`${hours}:${minutes}:${seconds}`);
      secondsPassed++;
    }, 1000);
  }
  function pause() {
    clearInterval(timerId);
    timerId = undefined;
  }

  $(window).blur(pause); // stop timer when user leaves tab
  $(window).focus(resume); // continue timer when user comes back

  resume(); // now start the timer
}

现在如何使那个面向对象? 只需从createTimer返回一个 object 。 resumepause作为该 object 的方法。 也许添加更多的方法来启动、停止、重置,无论你需要什么。 也许使用 object 上的属性而不是secondsPassed局部变量。 或者使用 getter 公开局部变量。

And to make it reusable, of course you can make createTimer accept arguments, from the selector of the output element, to the output element itself, to a callback function that will be called with the current time on every tick.

编辑:有了这个答案,你必须先自己实现定时器 class 。 该代码仅显示如何命名计时器的方法、如何创建实例并调用其函数。 计时器应该(原则上“关注点分离”)只处理计数并提供所需的功能,如启动和停止。

如果您想为您的计时器提供 OOP 解决方案,则不应让计时器 class 知道 DOM 容器的 ID(就像您对问题的评论之一)。

您应该使用以下内容阅读该主题: https://appdividend.com/2019/05/22/javascript-class-example-how-to-use-class-in-javascript-tutorial/

让我们假设您已经实现了 class。 您上面的代码应如下所示:

// Create own scope for the function, so that variable are not assigned to windows-object.
(function() {
    let secondsPassed = 0;

    let timer = new Timer();
    // events, if necessary
    timer.onTick((seconds) => { secondsPassed = seconds });
    timer.onStop(() => { secondsPassed = 0; })

    // Called by a button
    function startTimer() {
        timer.start();
    }

    // Example: Display alert with current timer seconds on click
    function displaySecondsOfTimer() {
        alert(timer.getSeconds());
    }

    $(window).blur(function() {
        timer.stop(); // stop timer when user leaves tab
    });

    $(window).focus(function() {
        timer.start(); // continue timer when user comes back
    });
})();

所以我认为,你有一个很好的例子来编码你的第一个定时器 class 在本机 JavaScript ::)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM