Estoy haciendo un teclado virtual, donde al presionar una tecla física, su réplica debe resaltar en la pantalla. La cosa es que no pasa absolutamente nada, cuando le doy al botón. El programa escucha el evento del mouse, esta parte está bien. Extracción de código:
_createKeys() { const fragment = document.createDocumentFragment(); const layout = [ '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'backspace', 'tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 'caps lock', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '\\', 'enter', 'shiftLeft', '\\', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 'shiftRight', 'arrowUp', 'Ctrl', 'Win', 'Alt', 'space', 'Alt', 'Ctrl', 'arrowLeft', 'arrowDown', 'arrowRight' ]; const createIconHTML = (icon_name) => { return `<i class="material-icons">${icon_name}</i>`; }; layout.forEach(key => { const keyElement = document.createElement('button'); const lineBreak = ['backspace', ']', 'enter', 'arrowUp'].indexOf(key) !== -1; keyElement.setAttribute('type', 'button'); keyElement.classList.add('key'); switch(key) { case 'caps lock': keyElement.classList.add('key-wide'); keyElement.textContent = 'CapsLock'; keyElement.addEventListener("click", () => { this._toggleCapsLock(); keyElement.classList.toggle('key-caps', this.properties.capsLock); }); keyElement.addEventListener('keydown', (e) => { if(e.key === 'CapsLock') console.log('pressed'); }); } fragment.appendChild(keyElement); if (lineBreak) { fragment.appendChild(document.createElement('br')); } }); return fragment; },
Debe agregar el detector de eventos keydown
al document
no keyElement
lo contrario, el evento solo se activará si el elemento tiene el foco, lo que definitivamente no sucederá si el cursor está en un campo de texto en otro lugar de la página.
En vez de :
keyElement.addEventListener('keydown', (e) => { if(e.key === 'CapsLock') console.log('pressed'); });
Usar :
document.addEventListener('keydown', (e) => { if(e.key === 'CapsLock') console.log('pressed'); });
Sin embargo, agregar ~100+ detectores de eventos al document
no sería una buena idea. Debe crear un detector de eventos único en el document
que escuche todos los eventos de pulsación de tecla y active la tecla virtual adecuada.
layout.forEach(key => { ... keyElement.dataset.key = encodeURIComponent(key); ... }); document.addEventListener('keydown', event => { let k = encodeURIComponent(event.key); let vkey = document.querySelector(`[data-key="${k}"]`); vkey?.classList.add('pressed'); });
solo llama al addEventListener
dentro del caso del interruptor también para document
no el elemento, lo que ocurre solo con mayúsculas, por lo que esto debe salir. Además, dado que es solo un case
de switch
, ¿por qué no usará la condición if en su lugar? haría el código más legible para usted.