Detect alternating key events

Sher Afghan from

I'm writing a script for the following task:

The task is for participants to alternately press the a and b keys on the keyboard as quickly as possible for 10 minutes. Every time a participant successfully press the a key followed by the b key, they should receive a point. Points should only be awarded for alternating key presses, pressing the a key or the b key without alternating between the two should not result in points.

The part of the problem I am asking about is the detection of alternating key events. I attempted this myself and ended up with the code below, but it does not achieve the desired result and I'm getting the following error:

Uncaught ReferenceError: x is not defined

... but I just don't understand what I'm doing wrong.

How can I fix my code and achieve the desired result?

var points = 0;

document.addEventListener('keydown', function(event) {
    var x = event.code;
});

document.addEventListener('keydown', function(event) {
    if (x == 'KeyA' && event.code == 'KeyB') {
        points = points + 1;
        document.getElementById("points").innerHTML = points;
    }
});
<p>Points: <span id="points">0</span></p>

javascript keyevent dom-events

Answers

answered 2 months ago Tiny Giant #1

You only need one event listener, and you need to define the a key press state variable (x) outside of the listener function so that it can be referenced by subsequent executions of the listener function.

You also need to make sure that you reset the a key press variable after the b key press.

it is also generally a good idea to cache your references to elements, rather than selecting the element from the DOM each time your listener function runs, and using textContent instead of innerHTML bypasses the HTML parser.

const target = document.getElementById('points');
var points = 0, x;

document.addEventListener('keydown', function(event) {
    if(event.key === 'a') x = true; // If this is an `a` key event, set x to true
    if(event.key === 'b') {
        // if this is a `b` key event and a was not pressed, return early
        if(!x) return; 
        // otherwise increment the points variable and assign the result to 
        // the textContent property of the target element
        target.textContent = ++points; 
        // remember to set x to false again
        x = false;
    }
});
<p>Points: <span id="points">0</span></p>