javascriptkeyup

How to store simultaneous keypresses


When I use the key-up event listener in JavaScript, the keys "wait" before starting again. I think it's because the key-up needs to listen to specific keys but for me that hasn't worked yet.

I have tried using different tutorials for different perspectives on this problem, but none of them have worked for me yet... I think I just need to not use the key-up event listener but I'm not sure how. I only have only known JavaScript for a few weeks so I don't know how to use advanced methods for things.

var key = "";
document.addEventListener('keyup', e => { key = ""; });
document.addEventListener('keydown', e => { key = e.code; });
setInterval(e => {
    document.getElementById('test').innerText = key;
}, Infinity);
<p>Press and hold keys...</p>
<p id="test"></p>
If you were to press A, then press D right afterward, it would wait a bit before saying D is pressed. That is a problem because I'm trying to be able to make a gamepad for pressing multiple keys at once.


Solution

  • Use a Set (mdn reference) to track all keys currently pressed. Your current approach of using a single string, key, is impractical for storing multiple keys.

    const codes = new Set();
    
    const updateDisplay = (mode, evt) => {
      evt.preventDefault();
      if (mode === 'add') codes.add(evt.code);
      if (mode === 'rem') codes.delete(evt.code);
      document.querySelector('.state').textContent = [ ...codes ].join(' + ') || '(no keys)';
    }
    
    window.addEventListener('keydown', evt => updateDisplay('add', evt));
    window.addEventListener('keyup', evt => updateDisplay('rem', evt));
    
    window.addEventListener('focus', () => document.querySelector('.focus').style.display = 'none');
    window.addEventListener('blur', () => document.querySelector('.focus').style.display = '');
    <div class="focus">WINDOW IS UNFOCUSED; CANNOT PROCESS KEY EVENTS (please click)</div>
    <p>Press and release buttons (potentially many at once)</p>
    <p>Current state: <span class="state">(no keys)</span></p>