Muranx
@Muranx
кто понял this тот в цирке не смеётся

Как приручить событие «keydown» в браузере?

Здравствуйте!

Мне нужно увеличить скорость персонажа при зажатой клавише пробел.
document.addEventListener("keydown", e=>{
	if(e.key === " "){
		 setMovementSpeedToSpeedUp(); // увеличиваем скорость персонажа
	};
});

document.addEventListener("keyup", e=>{
	if(e.key === " "){
		 setMovementSpeedToNormal(); // устанавливаем скорость на нормальное значение
	};
});

проблема этого кода, что в браузере при зажатой клавише - событие срабатывает очень много раз, пока клавишу не отпустят. Получается за 2 секунды зажатого пробела, функция setMovementSppedToSpeedUp() сработает кучу раз. А мне это не нужно. Я могу победить эту ситуацию путём ввода в программу некого состояния по типу gameSpeedIncreasedState (состояние указывает на то увеличена ли скорость игры или нет в данный момент)

let gameSpeedIncreasedState = false;

function increaseMovementSpeed(){

	if(gameSpeedIncreasedState) return;

	gameSpeedIncreasedState = true;

	// код для увеличения скорости игрока

};

Но это же дополнительное условие if(gameSpeedIncreasedState) return; которое будет проверяться каждый раз, когда срабатывает обработчик события зажатой кнопки (т.е. очень много раз), хотелось бы избежать лишней переменной gameSpeedIncreasedState, да ещё и проверки. Может у кого то есть подходящее решение, буду благодарен, пока ничего просто в голову не пришло!
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
delphinpro
@delphinpro Куратор тега JavaScript
frontend developer
  1. вешаем на keydown одноразовый обработчик {once: true}
  2. в обработчике на keyup повторяем навешивание одноразового хэндлера на keydown


Будет срабатывать один раз при нажатии.

А вообще, если требуется одноразовое срабатывание за одно нажатие, то почему не использовать keypress?
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@alexalexes
Чтобы вовремя удалить обработчики, нужно их методы деанонимизировать - присвоить имена или иметь где-то указатели на оригинал обработчика, чтобы внутри обработчика он смог снять сам себя с события.
let setSpeedToUpHandler = function(e)
{
  if(e.key === " "){
      document.removeEventListener("keydown", setSpeedToUpHandler); // удаляем текущий обработчик с этого типа события 
     setMovementSpeedToSpeedUp(); // увеличиваем скорость персонажа
  };
};
let setMovementSpeedToNormalHandler = function(e)
{
  if(e.key === " "){
     document.removeEventListener("keyup", setMovementSpeedToNormalHandler); // удаляем текущий обработчик с этого типа события 
     setMovementSpeedToNormal(); // устанавливаем скорость на нормальное значение
  };
};
document.addEventListener("keydown", setSpeedToUpHandler);
document.addEventListener("keyup", setMovementSpeedToNormalHandler);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы