JS按住按键触发事件存在延迟问题求助
解决按住按键时游戏对象持续移动的问题
这个问题其实是浏览器的默认行为导致的——当你按住按键时,浏览器会先触发一次keydown事件,然后等待一小段时间(就是你感受到的停顿),才会开始重复触发keydown,这是为了模拟打字时的输入逻辑,但对游戏来说就很不友好了。
要解决这个问题,我们需要自己跟踪按键的状态,配合定时器来实现持续移动,而不是依赖浏览器的重复触发。下面是具体的实现步骤和代码:
核心思路
- 用一个对象来记录当前哪些按键处于按下状态
- 监听
keydown事件,标记对应按键为按下状态 - 监听
keyup事件,标记对应按键为松开状态 - 用一个循环定时器(比如
setInterval),每隔固定时间检查按键状态,如果目标按键处于按下状态,就执行move()函数
完整代码示例
// 记录按键状态的对象 const keysPressed = {}; // 初始化监听事件 document.addEventListener('keydown', (evt) => { const keyCode = evt.which || evt.keyCode; // 标记按键为按下状态 keysPressed[keyCode] = true; }); document.addEventListener('keyup', (evt) => { const keyCode = evt.which || evt.keyCode; // 标记按键为松开状态 delete keysPressed[keyCode]; }); // 定时器循环检查按键状态,这里设置每16ms执行一次(大约60帧每秒) setInterval(() => { // 检查左箭头键(keyCode 37)是否按下 if (keysPressed[37]) { move(); } }, 16); // 你的move函数,示例实现 function move() { // 这里写你的对象移动逻辑,比如改变元素的left值 const player = document.getElementById('player'); let currentLeft = parseInt(window.getComputedStyle(player).left) || 0; player.style.left = `${currentLeft - 5}px`; }
为什么这个方案更好?
- 完全消除了浏览器的停顿问题,按住按键后对象会立刻持续移动
- 可以同时处理多个按键的按下(比如同时按左右上下),适合复杂的游戏控制
- 定时器的间隔可以根据游戏帧率调整,比如16ms对应60FPS,让移动更流畅
另外要注意,记得在游戏结束或者不需要的时候清除定时器,避免不必要的性能消耗:
// 保存定时器ID const moveInterval = setInterval(() => { if (keysPressed[37]) { move(); } }, 16); // 清除定时器的方法 // clearInterval(moveInterval);
内容的提问来源于stack exchange,提问作者Yannic
相关产品推荐
相关产品推荐

