Home > Mobile >  How to refactor my stopwatch code to Vanilla JavaScript?
How to refactor my stopwatch code to Vanilla JavaScript?

Time:12-10

everyone! I have a small code written in Vue.JS for the stopwatch. After writing I realized that there are small losses in time (For every 30 real seconds, the browser marks about 27-28 seconds), as well as when folding deposits the time account stops. Tell me, please, how to my code, I can insert the use of localStorage to avoid wasting time when coagulating and where better to compare with the real time to avoid the usual losses?

Stopwatch code:

<template>
  <div id="clock">
    <span  ref="watch">00:00</span>
  </div>
</template>

<script>
export default {
  name: "MyTimer",
  data() {
    return {
      minutes: 0,
      seconds: 0,
      miliseconds: 0,
      interval: null,
    }
  },
  mounted() {
    const watch = this.$refs.watch;
    clearInterval(this.interval);
    this.interval = setInterval(() => {
      this.miliseconds  = 10;
      let dateTimer = new Date(this.miliseconds);
      watch.innerHTML = ('0'   dateTimer.getUTCMinutes()).slice(-2)   ':'   ('0'   dateTimer.getUTCSeconds()).slice(-2);
    }, 10)
  }
}
</script>

<style scoped>

#clock {
  background: #EDEDED;
  padding: 1%;
  border-radius: 12px;
  text-align: center;
}

.time {
  font-weight: 900;
  font-size: 2.125em;
  letter-spacing: 0.015625em;
  color: #373745;
}
</style>

Please help embed localStorage and real past tense comparison to make the stopwatch more accurate and avoid real past tense losses.

CodePudding user response:

I think I got all things covered here. The save and load isn't used in the example due to localStorage not working within sandbox.

class stopwatch {
    /** @param {HTMLElement} element */
    constructor(element) {
        this._el = element;
        if(this._el) {
            this._el.innerText = "00:00";
        }
    }

    laps = [];

    totalMilliseconds = 0;
    totalSeconds = this.totalMilliseconds / 1000.0;
    totalMinutes = this.totalMilliseconds / 60000.0;
    totalHours = this.totalMilliseconds / 3600000.0;

    _startTime = 0;
    _interval = null;
    start = (reset) => {
        if(reset) {
            this.laps.splice(0, this.laps.length);
        }
        this._startTime = performance.now();
        this._interval = setInterval(this._render, 10);
    };
    lap = () => { 
        this.laps.push(performance.now() - this._startTime); 
        this._startTime = performance.now();
    };
    stop = () => {
        this.laps.push(performance.now() - this._startTime); 
        this._startTime = 0;
        clearInterval(this._interval);
        this._interval = null;
    };

    save = () => {
        if(this._interval) {
            this.stop();
        }

        localStorage.setItem('js_stopwatch', JSON.stringify({laps: this.laps}));
    };
    
    load = () => {
        const data = JSON.parse(localStorage.getItem('js_stopwatch'));
        if(data && data.laps) {
            this.laps = data.laps;
            this._startTime = performance.now();
            this._render();
            this.start();

            return true;
        }
    };

    _msToParts = (milliseconds) => {
        const h =  Math.floor(milliseconds / (1000 * 60 * 60));
        milliseconds -= (h * 60 * 60 * 1000);
        const m =  Math.floor(milliseconds / (1000 * 60));
        milliseconds -= (m * 60 * 1000);
        const s =  Math.floor(milliseconds / (1000));
        milliseconds -= (s * 1000);
        const ms = Math.floor(milliseconds);

        return {
            hours: h,
            minutes: m,
            seconds: s,
            milliseconds: ms,
        };
    };

    _render = () => {
        this.totalMilliseconds = this.laps.reduce((pv, cv, i) => pv   cv, (performance.now() - this._startTime));
        const parts = this._msToParts(this.totalMilliseconds);

        if(this._el) {
            this._el.innerText = `${parts.hours ? `${parts.hours}:` : ''}${parts.minutes.toString().padStart(2, '0')}:${parts.seconds.toString().padStart(2, '0')}`;
        }
    };
}

const el = document.getElementById("clock");
const sw = new stopwatch(el);
sw.start();
#clock {
  background: #EDEDED;
  padding: 1%;
  border-radius: 12px;
  text-align: center;
}

.time {
  font-weight: 900;
  font-size: 2.125em;
  letter-spacing: 0.015625em;
  color: #373745;
}
<span id="clock">00:00</span>

  • Related