如何在js中使用键盘事件创建计数计时器
How to create countup timer with keyboard events in 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 但它似乎确实如此
这是 link 我目前所做的 timer
我检查了您的代码,发现它需要进行太多更改。
- 您仅将
state
和 isFired
用作变量,但您需要在重新呈现时保留它们的值。因此,这些必须是状态。
- 您没有解除绑定在
keyup
和 keydown
上的同一个侦听器。
- 根据您当前的代码,您的计时器将在 1 日
keyup
开始,然后在下一个 keydown
它将停止在原来的位置。现在,在下一个 keydown
它将重置为 0,然后在 keyup
,计时器将再次从 0 开始。
我修改了您的代码并在此处查看工作更改,
https://codesandbox.io/s/xenodochial-shannon-im8zt?file=/src/App.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 但它似乎确实如此
这是 link 我目前所做的 timer
我检查了您的代码,发现它需要进行太多更改。
- 您仅将
state
和isFired
用作变量,但您需要在重新呈现时保留它们的值。因此,这些必须是状态。 - 您没有解除绑定在
keyup
和keydown
上的同一个侦听器。 - 根据您当前的代码,您的计时器将在 1 日
keyup
开始,然后在下一个keydown
它将停止在原来的位置。现在,在下一个keydown
它将重置为 0,然后在keyup
,计时器将再次从 0 开始。
我修改了您的代码并在此处查看工作更改,
https://codesandbox.io/s/xenodochial-shannon-im8zt?file=/src/App.js