如何在js中使用键盘事件创建计数计时器

问题描述

我正在创建一个程序,当我点击“keyup”时计时器开始,当我点击“keydown”时停止,并在我下次点击“keydown”时重置计时器。

const Timer = () => {
  const [timer,setTimer] = useState(0);
  let state = 0;
  let isFired = false;
  const increment = useRef(null);

  useEffect(() => {
    window.addEventListener('keydown',(e) => {
      if (isFired) {
        if (e.code === 'Space' && state === 2) {
          e.stopPropagation();
          isFired = false;
          handleReset();
        }

        if (e.code === 'Space' && state === 1) {
          clearInterval(increment.current);
          state = 2;
        }
      }
    });

    window.addEventListener('keyup',(e) => {
      if (!isFired) {
        if (e.code === 'Space' && state === 0) {
          isFired = true;
          state = 1;
          handleStart();
        }
      }
    });

    return () => {
      window.removeEventListener('keydown',handleReset);
      window.removeEventListener('keyup',handleStart);
    };
  },[]);

  const handleStart = () => {
    increment.current = setInterval(() => {
    // DON'T copY THIS BIT
      setTimer((timer) => timer + 10);
    },10);
  };

  const handleReset = () => {
    clearInterval(increment.current);
    setTimer(0);
    state = 0;
  };
  // DON'T copY THIS BIT

  const formatTime = () => {
    console.log(timer);
    const getMilliSeconds = `0${timer % 60}`.slice(-2);
    const seconds = `${Math.floor(timer / 60)}`;
    const getSeconds = `0${seconds % 60}`.slice(-2);
    const getMinutes = `0${Math.floor(timer / 3600)}`.slice(-2);

    // return `${getHours} : ${getMinutes} : ${getSeconds}`;
    if (getMinutes === '00') {
      return `${getSeconds}.${getMilliSeconds}`;
    } else {
      return `${getMinutes} : ${getSeconds} : ${getMilliSeconds} `;
    }
  };

  // const formatTime = () => {
  //   // const milliSeconds = `0${}`;
  //   const seconds = `0${Math.floor(timer / 100)}`;
  //   const minute = `0${Math.floor(timer / 3600)}`.slice(-2);

  //   return `${minute}.${seconds}`;
  // };

  return (
    <div className="Timer">
      <h1>{formatTime()}</h1>
    </div>
  );
};

到目前为止我已经尝试过这个 它大部分时间都有效,但有时会出现故障 而且我知道时间格式不正确,增量也是错误的。有时它会在“keydown”上停止并在同一笔划中触发“keyup”,使其从零开始重置计时器我不完全知道它是否在同一笔划上触发 keyup 但似乎确实如此

这是我目前所做工作的链接timer

解决方法

我检查了您的代码,发现它需要进行太多更改。

  1. 您仅将 stateisFired 用作变量,但在重新渲染时需要它们的持久值。因此,这些必须是状态。
  2. 您没有取消绑定在 keyupkeydown 上绑定的同一个侦听器。
  3. 根据您当前的代码,您的计时器将从第 1 个 keyup 开始,然后在下一个 keydown 停止。现在,在下一个 keydown 它将重置为 0,然后在 keyup,计时器再次从 0 开始。

我修改了您的代码并在此处看到了有效的更改,

https://codesandbox.io/s/xenodochial-shannon-im8zt?file=/src/App.js

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...