Помогите починить код

Рейтинг: -1Ответов: 1Опубликовано: 27.01.2023

Чтобы при нажатии на клавиатуру тот блок с таким же ключом key изменил задний фон

let keyboard = ['Escape', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'Backspace', 'Tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\\', 'CapsLock', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", 'Enter', 'Shift', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 'ArrowUp', 'Control', 'Meta', 'Alt', ' ', 'ArrowLeft', 'ArrowDown', 'ArrowRight']


let init = () => {
  for (let i = 0; i < keyboard.length; i++) {
    let p = document.createElement('p')
    p.innerText = keyboard[i]
    p.style.display = 'inline-flex'
    p.classList.add('k-key')

    document.onkeydown = (e) => {
      let res = e.key
      if (res === p.textContent) {
        p.style.backgroundColor = "red"
      }
    }
    document.body.append(p)
  }


}
init()
.k-key {
  width: 80 px;
  height: 50 px;
  border: 1 px solid black;
  margin: 3 px;
  float: left;
}

Ответы

▲ 2

Давайте посмотрим, что происходит в вашем коде:

for (let i = 0; i < keyboard.length; i++) {

...

    document.onkeydown = (e) => { ... }

...

}

Рассудим логически: вы в этом месте на каждой итерации цикла перезаписываете onkeydown, а значит у вас он будет срабатывать только так, как вы его записали в последний раз, т.е. только на последний созданный элемент, а именно с текстом ArrowRight. Если вы хотите идти именно этим путем, то вам нужно через addEventListener вешать обработчик нажатия :

let keyboard = ['Escape', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'Backspace', 'Tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\\', 'CapsLock', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", 'Enter', 'Shift', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 'ArrowUp', 'Control', 'Meta', 'Alt', ' ', 'ArrowLeft', 'ArrowDown', 'ArrowRight']


let init = ()=>{
    for (let i = 0; i < keyboard.length; i++) {
        let p = document.createElement('p')
        p.innerText = keyboard[i]
        p.style.display = 'inline-flex'
        p.classList.add('k-key')
        
        document.addEventListener('keydown',  (e) => {
            let res = e.key
            if (res === p.textContent) {
                p.style.backgroundColor = "red"
            }
        });
        document.body.append(p)
    }

    
}
init()
.k-key{
    width: 80px;
    height: 50px;
    border: 1px solid black;
    margin: 3px;
    float: left;
}

Но, на мой взгляд, не совсем рационально вешать столько обработчиков, достаточно и одного, который справится со всем. Можно все создаваемые элементы класть в отдельный массив. Когда произойдет нажатие, через метод find() искать совпадение содержимого элемента с нажатой кнопкой. И если элемент найден -- поменять ему фон.

Пример:

let keyboard = ['Escape', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'Backspace', 'Tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\\', 'CapsLock', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", 'Enter', 'Shift', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 'ArrowUp', 'Control', 'Meta', 'Alt', ' ', 'ArrowLeft', 'ArrowDown', 'ArrowRight']
let resMass = [];

let init = () => {
  for (let i = 0; i < keyboard.length; i++) {
    let p = document.createElement('p')
    p.innerText = keyboard[i]
    p.style.display = 'inline-flex'
    p.classList.add('k-key');
    document.body.append(p)
    resMass.push(p);
  }

  document.onkeydown = (e) => {
      let res = e.key;
      let elem = resMass.find(item => item.textContent == res);
      if (elem) elem.style.backgroundColor = 'red';
   }
}
init()
.k-key {
  width: 80px;
  height: 50px;
  border: 1px solid black;
  margin: 3px;
  float: left;
}