JavaScript EventListener在一个键触发keyup后会停止多个keydown



早上好,我的EventListener有问题。我有一个keydown事件,在该事件中我检查是否按下了多个键或单次按下。

我的问题:我有三种情况:(W+A(-(W+D(或W。在我按下W+A并释放A键后,会触发keyup事件。因此,从逻辑上讲,keydown事件是停止的,但要重新启动keydown事件,我必须释放W并再次按下它。即使在A键向上之后W键仍然向下,keydown事件也不会再次启动。

我的问题:有没有办法通过将keydown事件设置为true来重新启动事件是否有办法让keydown事件在不再次按下的情况下识别仍在按下的键。

Keydown事件:

document.addEventListener("keydown", event => {
if (!keyStatus) { keyStatus = keyDown(event); }
if (Object.keys(keysDown).length < 2) {
keysDown = (keysDown || []);
} else { Object.keys(keysDown).forEach(k => delete keysDown[k]); }
keysDown[event.keyCode] = true;
switch (true) {
case keysDown[65] && keysDown[87]:
if (currentCode.includes(68) || (currentCode.length <= 1 && currentCode.includes(87))) { currentCode = [] }
if (currentCode.includes(65) && currentCode.includes(87)) {
break;
} else { currentCode.push(65, 87); }
multiStatus = true
break;
case keysDown[68] && keysDown[87]:
if (currentCode.includes(65) || (currentCode.length <= 1 && currentCode.includes(87))) { currentCode = [] }
if (currentCode.includes(68) && currentCode.includes(87)) {
break;
} else { currentCode.push(68, 87) }
multiStatus = true
break;
case keysDown[87] && !multiStatus:
if (currentCode.includes(65) || currentCode.includes(68)) { currentCode = [] }
if (currentCode.length <= 1 && currentCode.includes(87)) {
break;
} else { currentCode.push(87) }
break;
default:
multiStatus = false
break;
}
});
document.addEventListener("keyup", event => {
if (keyStatus) { keyStatus = keyUp(event); currentCode = []; multiStatus = false }
});

我希望有人能帮助我。提前感谢

如果不是不可能的话,备份事件是非常困难和耗时的。相反,单独注册keyevents,创建一个"主循环"来读取注册表(以及执行其他操作(。下面的代码片段并不是适合您代码的直接解决方案,相反,它在一个如何在屏幕上引导元素的简单示例中介绍了按键注册表和主循环。

const ball = {
a: 0,
d: 0,
w: 0,
z: 0,
speed: 2,
posX: 0,
posY: 0,
el: document.querySelector('.ball')
}
function regKeyStrokes(e) {
if (!'adwz'.includes(e.key)) {return;}
ball[e.key] = (event.type === 'keyup') ? 0 : 1;
}
function animate() {
const dX = ball.a * -ball.speed + ball.d * ball.speed;
const dY = ball.w * -ball.speed + ball.z * ball.speed;
const cS = (dX * dY === 0) ? 1 : 0.707;
ball.posX += cS * dX;
ball.posY += cS * dY;
ball.el.style.transform = `translate(${ball.posX}px, ${ball.posY}px)`;
requestAnimationFrame(animate);
}
document.addEventListener('keyup', regKeyStrokes);
document.addEventListener('keydown', regKeyStrokes);
requestAnimationFrame(animate);
.ball {
position: fixed;
width: 50px;
height: 50px;
background: red;
border-radius: 100%;
}
<div class="ball"></div>

在代码段中,注册表项是ball对象的一部分(当然,这可以是一个单独的对象(。寄存器中的属性由使用的键命名。键敲击和释放是独立于主循环进行侦听的,并且键注册表与这两个事件的侦听器保持最新。

最新更新