按住按键时事件监听器延迟的解决方案咨询
解决长按按键移动停顿的问题
你的推测没错,这个停顿确实是浏览器的按键重复默认延迟导致的,但不需要禁用这个默认行为,问题核心出在当前的输入处理逻辑——每次触发keydown后只执行一次移动就重置了方向状态,必须等浏览器再次触发keydown才能继续移动,这才引发了停顿。
核心修改思路
- 用
keydown事件标记对应方向为true,不在移动逻辑里重置方向状态 - 新增
keyup事件,按键松开时把对应方向标记为false - 动画循环里持续根据当前方向状态执行移动,直到按键松开
修改后的完整代码
movement(player) { let movements = { up: false, down: false, left: false, right: false, speed: 0, maxSpeed: 10, lastMove: null } function handleKeyDown(e) { const key = e.key.toLowerCase(); // 兼容大小写输入 e.preventDefault(); switch(key) { case "w": movements.up = true; break; case "s": movements.down = true; break; case "a": movements.left = true; break; case "d": movements.right = true; break; } } function handleKeyUp(e) { const key = e.key.toLowerCase(); switch(key) { case "w": movements.up = false; break; case "s": movements.down = false; break; case "a": movements.left = false; break; case "d": movements.right = false; break; } // 松开按键后重置速度 movements.speed = 0; } function updateMovement(x) { let direction = null; // 保留原有的方向互斥逻辑,也可自行修改为支持斜向移动 if (movements.up) direction = "up"; else if (movements.down) direction = "down"; else if (movements.left) direction = "left"; else if (movements.right) direction = "right"; if (direction) { // 更新角色朝向图片 player.src = `${x.data.entities.player.image}${direction}.png`; // 执行位置移动 if (direction === "up" || direction === "down") { player.style.top = `${parseInt(player.style.top) + (direction === "up" ? -1 : 1) * movements.speed}px`; } else { player.style.left = `${parseInt(player.style.left) + (direction === "left" ? -1 : 1) * movements.speed}px`; } movements.lastMove = direction; // 加速逻辑 if (movements.speed < movements.maxSpeed) { movements.speed++; } } else { // 无方向输入时重置速度 movements.speed = 0; } requestAnimationFrame(() => updateMovement(x)); } // 绑定输入事件 document.addEventListener("keydown", handleKeyDown); document.addEventListener("keyup", handleKeyUp); // 启动动画循环 requestAnimationFrame(() => updateMovement(this)); }
关键改动说明
- 拆分输入处理为
handleKeyDown和handleKeyUp,分别负责方向状态的激活与关闭 - 移除移动逻辑里重置方向状态的代码,让方向状态持续保持直到按键松开
- 优化按键判断为
switch结构,更简洁高效,同时兼容大小写输入 - 增加无输入时的速度重置逻辑,角色停止移动后速度自动归零
这样修改后,角色会在按住按键时持续平滑移动,完全避开浏览器的按键重复延迟问题。
内容的提问来源于stack exchange,提问作者user21484220
相关产品推荐
相关产品推荐

