typescript 实现秒表的最有效方法?

ruyhziif  于 2023-05-30  发布在  TypeScript
关注(0)|答案(3)|浏览(192)

我想跟踪用户点击按钮所需的时间。我已经解决了这个问题,但如果有更好的解决方案的话,我会想要一个更好的解决方案。这是我的:

export class MainComponent implements OnInit {

    timer : number = 0;
    intervalId : number;

    constructor() {
      this.intervalId = setInterval(() => {
        this.timer++;
      }, 1000);
    }

    ngOnInit() {}

    buttonClick = function() {
    alert(this.timer);
    this.timer = 0;
    }
}
9jyewag0

9jyewag01#

使用performance.now()获得准确的时间戳(或回退到new Date().getTime()),并计算UI更新回调的差异(通过setInterval)。不要使用setInterval本身来计算时间--你不能假设setInterval调用实际上每1000 ms被精确地调用一次。
注意:我还将定时器逻辑移到了ngOnInit函数中,而不是constructor

export class MainComponent implements OnInit {

    private start: number = null;
    private uiTimerId: number = null;

    constructor() {
    }

    private updateUI(): void {

        let delta = performance.now() - this.start;
        this.someUIElement.textContent = delta.toFixed() + "ms";
    }

    ngOnInit() {

        this.start = parseFloat( window.localStorage.getItem( "timerStart" ) );
        if( !this.start ) {
            this.start = performance.now();
            window.localStorage.setItem( "timerStart", this.start );
        }

        this.uiTimerId = window.setInterval( this.updateUI.bind(this), 100 ); // 100ms UI updates, not 1000ms to reduce UI jitter
    }

    buttonClick = function() {
        if( this.uiTimerId != null ) {
            window.clearInterval( this.uiTimerId );
            window.localStorage.removeItem( "timerStart" );
        }
    }
}
xzv2uavs

xzv2uavs2#

首先,我们在typescript中声明成员函数的方式有点不同,所以buttonClick应该是这样的

buttonClick() {
  alert(this.timer);
  this.timer = 0;
}

正如@Dai的评论中提到的,在开始时(在ngOnInit)获取系统时间,并从单击时的系统时间中减去它,将需要更少的操作,并且更准确。

ngOnInit() {
  this.startTime = localStorage.startTime ? JSON.parse(localStorage.startTime) : (new Date().getTime());
  localStorage.setItem('startTime', JSON.stringify(this.startTime));
}

buttonClick() {
  this.startTime = JSON.parse(localStorage.startTime);
  alert((this.startTime - (new Date().getTime())) / 1000);
}

编辑:我编辑了答案,以显示您必须使用localStorage来持久化值。这与上面的答案类似,但是使用了idomatic typescript。我想前面的答案有很多es 5的经验,并诉诸于这些方法(没有错)。我发现这种风格更容易和更清晰。我会重新采取一个Angular 教程。尝试在他们的网站上浏览英雄,并使用带有Angular Essentials插件的Visual Studio代码,因为这将正确地Lint和格式化您的代码,以便您可以习惯惯用的类型脚本。干杯

e5njpo68

e5njpo683#

你可以用下面的代码代替增量计时器。当标签处于非活动状态时,计时器的增量将被更改。我以最有效的方式创建了一个秒表。您可以将一个选项卡移动到另一个选项卡。时间计数值不会改变。您可以重置,暂停和播放。您可以访问链接了解详情。

seconds: string = "00";
  minutes: string = "00";
  hours: string = "00";
   timer(){
    let mcountercal = 0;
    let currentSeconds = parseInt(this.seconds);
    let currentMinutes = parseInt(this.minutes);
    let currentHours = parseInt(this.hours);
    this.counter = currentHours * 3600000 + currentMinutes * 60000 + currentSeconds * 1000
    const startTime = Date.now() - (this.counter || 0);
    this.timeoutId = setInterval(() => {
      this.counter = Date.now() - startTime;
      currentHours = Math.floor(this.counter / 3600000);
      currentMinutes = Math.floor(this.counter / 60000) - currentHours * 60;
      mcountercal = Math.floor(this.counter / 60000);
      currentSeconds = Math.floor(this.counter / 1000) - mcountercal * 60;     
      this.hours = this.getFormattedTimeStamp(currentHours.toString());
      this.minutes = this.getFormattedTimeStamp(currentMinutes.toString())
      this.seconds = this.getFormattedTimeStamp(currentSeconds.toString())
}

getFormattedTimeStamp(timestamp:any) {
  return timestamp < 10 ? "0" + timestamp : timestamp;
}

https://stackblitz.com/github/Ashraf111/StopWatchWhenTabActiveAndInactive

相关问题