📜  反应原生秒表 - Javascript (1)

📅  最后修改于: 2023-12-03 15:22:53.139000             🧑  作者: Mango

原生Javascript反应秒表

这个Javascript程序是一个基于浏览器的原生反应秒表,用于测试用户的反应时间。

React Stopwatch

特性
  • 用纯Javascript编写,无需使用任何库或框架。
  • 包含开始、停止和重置功能。
  • 可以记录测试结果,包括反应时间和用户反应的按钮。
  • 可自定义设置测试时间限制和按钮数目。
如何使用
  1. 首先,将CSS和Javascript文件引入到你的HTML文件中。
<link rel="stylesheet" href="styles.css">

<script src="script.js"></script>
  1. 然后,在你的HTML文件中添加以下标记:
<div class="container">
  <div class="game" data-limit="5000" data-buttons="4"></div>
  <button class="start">Start</button>
  <button class="stop">Stop</button>
  <button class="reset">Reset</button>
</div>

其中,data-limit属性设置了测试时间限制,以毫秒为单位。data-buttons属性设置了测试按钮的数量。

  1. 最后,在你的Javascript文件中创建一个新的ReactStopwatch对象并初始化。
const container = document.querySelector('.game');
const startBtn = document.querySelector('.start');
const stopBtn = document.querySelector('.stop');
const resetBtn = document.querySelector('.reset');

const stopwatch = new ReactStopwatch(container, startBtn, stopBtn, resetBtn);
stopwatch.init();
代码片段
class ReactStopwatch {
  constructor(container, startBtn, stopBtn, resetBtn) {
    this.container = container;
    this.startBtn = startBtn;
    this.stopBtn = stopBtn;
    this.resetBtn = resetBtn;
    this.gameTime = 0;
    this.testTime = null;
    this.timer = null;
    this.results = [];
    this.buttons = [];
    this.activeButton = null;
    this.isRunning = false;
  }

  init() {
    this.createButtons();
    this.attachEvents();
  }

  createButtons() {
    const numButtons = parseInt(this.container.dataset.buttons);

    for (let i = 1; i <= numButtons; i++) {
      const button = document.createElement('button');
      button.classList.add('button');
      button.setAttribute('data-button', i);
      button.innerHTML = i;
      this.container.appendChild(button);
      this.buttons.push(button);
    }

    this.activeButton = this.buttons[Math.floor(Math.random() * numButtons)];
    this.activeButton.classList.add('active');
  }

  attachEvents() {
    this.startBtn.addEventListener('click', () => this.startGame());
    this.stopBtn.addEventListener('click', () => this.stopGame());
    this.resetBtn.addEventListener('click', () => this.resetGame());

    this.container.addEventListener('click', (event) => {
      if (!this.isRunning) return;

      const button = event.target.closest('.button');
      if (!button) return;

      const time = new Date().getTime() - this.testTime;
      const result = { button: button.getAttribute('data-button'), time };
      this.results.push(result);

      this.highlightButton(button);
      this.setActiveButton();
    });
  }

  startGame() {
    this.gameTime = parseInt(this.container.dataset.limit);
    this.timer = setInterval(() => this.tick(), 10);
    this.testTime = new Date().getTime();
    this.isRunning = true;
  }

  stopGame() {
    clearInterval(this.timer);
    this.isRunning = false;
  }

  resetGame() {
    this.stopGame();
    this.results = [];
    this.buttons.forEach((button) => button.classList.remove('highlight', 'active'));
  }

  tick() {
    this.gameTime -= 10;
    if (this.gameTime < 0) {
      this.stopGame();
      this.highlightResults();
    }
  }

  highlightButton(button) {
    button.classList.add('highlight');
    setTimeout(() => button.classList.remove('highlight'), 1000);
  }

  setActiveButton() {
    const numButtons = this.buttons.length;
    let buttonIndex = null;
    let button = null;

    while (buttonIndex === null || button.classList.contains('active')) {
      buttonIndex = Math.floor(Math.random() * numButtons);
      button = this.buttons[buttonIndex];
    }

    this.activeButton = button;
    button.classList.add('active');
  }

  highlightResults() {
    const resultsString = this.results.map(r => `${r.button} (${r.time}ms)`).join(', ');
    alert(`Results: ${resultsString}`);
  }
}