W3docs

События JavaScript keydown и keyup

Клавиатурные события JavaScript: различия keydown и keyup, объект KeyboardEvent (key и code, модификаторы, repeat), примеры горячих клавиш и навигации.

Введение в клавиатурные события JavaScript

Клавиатурные события JavaScript позволяют странице реагировать в момент, когда пользователь нажимает или отпускает клавишу. Они лежат в основе поиска по мере ввода, горячих клавиш, управления в играх и доступной навигации с клавиатуры. В этой главе рассматриваются два события, которые используются чаще всего, — keydown и keyup: объясняется, чем они отличаются, разбирается объект KeyboardEvent, получаемый каждым обработчиком, и приводятся практические запускаемые примеры.

Если вы только начинаете работать с событиями, сначала прочитайте Введение в события браузера и Обработка событий в DOM.

keydown и keyup: краткое сравнение

Оба события срабатывают на элементе, который в данный момент находится в фокусе (или на document, если ни один элемент специально не сфокусирован). Разница в том, когда именно в жизненном цикле нажатия они срабатывают:

СобытиеСрабатывает, когда…Повторяется при удержании?Типичное применение
keydownКлавиша нажатаДа — многократноГорячие клавиши, перемещение в игре, блокировка ввода
keyupКлавиша отпущенаНет — один раз за нажатиеОпределение конца нажатия, обновление интерфейса

Одиночное нажатие клавиши порождает одно событие keydown, а затем одно keyup. Удержание клавиши вызывает keydown снова и снова (автоповторы можно определить через event.repeat), а keyup срабатывает только один раз — когда клавиша наконец отпущена.

Устаревшее событие keypress объявлено deprecated и не должно использоваться в новом коде. Чтобы реагировать на текст, вводимый пользователем, используйте вместо него событие input.

Подробнее о keydown и keyup

Событие keydown

Событие keydown возникает, когда пользователь нажимает клавишу на клавиатуре. Оно срабатывает до того, как символ вставляется в поле, — именно поэтому здесь уместно вызывать event.preventDefault(), чтобы заблокировать ввод. Это событие удобно везде, где важен момент самого нажатия: в играх, при реализации возможностей специальных возможностей или в интерактивных элементах управления.

Пример события keydown

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example of Keydown Event</title>
<style>
  .highlight { background-color: yellow; }
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
  const inputField = document.getElementById('inputField');
  inputField.addEventListener('keydown', function(event) {
    console.log('Key down:', event.key);
    if (event.key === "Enter") {
      this.classList.add('highlight');
      event.preventDefault(); // Prevents the default action of the enter key
    }
  });
});
</script>
</head>
<body>
<input type="text" id="inputField" placeholder="Press 'Enter' to highlight" />
</body>
</html>

Код прослушивает событие keydown на поле ввода и проверяет, является ли нажатая клавиша «Enter». Если да, он изменяет цвет фона поля на жёлтый (класс highlight) и предотвращает стандартное поведение при нажатии Enter — отправку формы или другие типичные действия.

Событие keyup

Событие keyup срабатывает при отпускании клавиши, после события keydown (обратите внимание: устаревшее событие keypress объявлено deprecated и редко используется в современной веб-разработке). Это событие подходит для случаев, когда нужно знать, что нажатие завершилось, — например, при обновлении интерфейса или управлении мультимедийным контентом.

Пример события keyup

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example of Keyup Event</title>
<style>
  .normal { background-color: transparent; }
  .active { background-color: lightgreen; }
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
  const textArea = document.getElementById('textArea');
  textArea.addEventListener('keyup', function(event) {
    console.log('Key up:', event.key);
    if (event.key === "Control") {
      this.classList.remove('active');
      this.classList.add('normal');
    }
  });
  textArea.addEventListener('keydown', function(event) {
    if (event.key === "Control") {
      this.classList.add('active');
    }
  });
});
</script>
</head>
<body>
<textarea id="textArea" rows="4" cols="50" placeholder="Press and release 'Control' to see the effect"></textarea>
</body>
</html>

Этот код заставляет текстовую область менять цвет фона на светло-зелёный (класс active) при нажатии клавиши Control и возвращает его к прозрачному (класс normal) при её отпускании.

Объект KeyboardEvent

Каждый обработчик keydown и keyup получает объект KeyboardEvent. Знание его ключевых свойств позволяет писать надёжную логику обработки клавиатуры.

key и code

Эти два свойства легко перепутать, а неверный выбор — самая частая причина ошибок при работе с клавиатурой:

  • event.keyсимвол или именованное значение, которое производится с учётом раскладки клавиатуры и модификаторов. Нажатие клавиши A даёт "a" или "A" при зажатом Shift. Именованные клавиши: "Enter", "Escape", "ArrowLeft", " " (пробел).
  • event.codeфизическая клавиша на клавиатуре, независимо от раскладки или модификаторов. Одна и та же физическая клавиша всегда соответствует "KeyA" — будь то ввод a, A или другой раскладки.

Используйте key, когда важен вводимый символ (текстовый ввод, горячие клавиши, понятные пользователю). Используйте code, когда важна позиция клавиши — например, управление в игре через WASD, которое должно работать независимо от раскладки.

document.addEventListener('keydown', function (event) {
  console.log(event.key, event.code);
});
// Pressing Shift+A on QWERTY logs: "A" "KeyA"
// Pressing the space bar logs:     " " "Space"

Клавиши-модификаторы и repeat

Событие также сообщает, какие клавиши-модификаторы удерживаются, и является ли нажатие автоповтором ОС:

  • event.altKey, event.ctrlKey, event.shiftKey, event.metaKey — boolean-значения, равные true, пока соответствующий модификатор удерживается. (metaKey — это Cmd на macOS и клавиша Windows на других платформах.)
  • event.repeattrue, когда удерживаемая клавиша снова автоматически вызывает keydown. Проверяйте это свойство, чтобы игнорировать автоповторы.
document.addEventListener('keydown', function (event) {
  // Cross-platform "save" shortcut, ignoring auto-repeat.
  if ((event.ctrlKey || event.metaKey) && event.key === 's' && !event.repeat) {
    event.preventDefault();
    console.log('Save triggered');
  }
});

Прямое чтение флагов модификаторов (как показано выше) надёжнее, чем отслеживание отдельной переменной вроде ctrlPressed, потому что флаги гарантированно синхронизированы с реальным состоянием, даже если пропустить событие keyup.

Расширенное использование клавиатурных событий в JavaScript

Использование мощи клавиатурных событий keydown и keyup способно превратить обычные веб-приложения в высокоинтерактивные, доступные и эффективные платформы. Ниже рассмотрены более сложные сценарии: пользовательские горячие клавиши, управление в игре и реализация специальных возможностей.

Реализация пользовательских горячих клавиш

Горячие клавиши позволяют пользователям быстро выполнять действия, повышая продуктивность и удобство работы. В следующем примере показано, как создать простую горячую клавишу (Ctrl + S) для имитации сохранения — её можно адаптировать для запуска конкретных функций в реальных приложениях.

Пример пользовательских горячих клавиш

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Custom Hotkeys Example</title>
<script>
document.addEventListener('DOMContentLoaded', function () {
  let ctrlPressed = false;
  document.addEventListener('keydown', function(event) {
    if (event.key === "Control") {
      ctrlPressed = true;
    }
    // Use toLowerCase() for case-insensitive matching
    if (event.key.toLowerCase() === "s" && ctrlPressed) {
      alert('Saving your progress!');
      event.preventDefault(); // Prevent default to stop other actions like browser shortcuts
    }
  });

  document.addEventListener('keyup', function(event) {
    if (event.key === "Control") {
      ctrlPressed = false;
    }
  });
});
</script>
</head>
<body>
<p>Press <strong>Ctrl + S</strong> to simulate a save action.</p>
</body>
</html>

Управление в игре

Управление с клавиатуры критически важно для браузерных игр. В следующем примере реализовано простое управление стрелками для перемещения объекта-игрока внутри игрового поля — базовый шаблон, который можно расширить до более сложной игровой механики.

Пример управления в игре

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Game Control Example</title>
<style>
  #gameArea {
    width: 300px;
    height: 300px;
    border: 1px solid black;
    position: relative;
  }
  #player {
    width: 50px;
    height: 50px;
    background-color: red;
    position: absolute;
    top: 125px;
    left: 125px;
  }
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
  const player = document.getElementById('player');
  // Note: offsetLeft/Top don't account for container padding or scroll offsets.
  // For production, consider using getBoundingClientRect() or adding padding offsets.
  let posX = player.offsetLeft;
  let posY = player.offsetTop;
  document.addEventListener('keydown', function(event) {
    switch (event.key) {
      case "ArrowUp":
        posY -= 10;
        break;
      case "ArrowDown":
        posY += 10;
        break;
      case "ArrowLeft":
        posX -= 10;
        break;
      case "ArrowRight":
        posX += 10;
        break;
    }
    player.style.left = posX + 'px';
    player.style.top = posY + 'px';
  });
});
</script>
</head>
<body>
<div id="gameArea">
  <div id="player"></div>
</div>
<p>Use arrow keys to move the red square within the game area.</p>
</body>
</html>

Улучшение доступности

Улучшение доступности помогает сделать веб-приложения удобными для людей с ограниченными возможностями. В следующем примере события keydown используются для навигации по ссылкам с помощью клавиш-стрелок, что обеспечивает клавиатурную навигацию для пользователей, которые не могут пользоваться мышью.

Пример улучшения доступности

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Accessibility Navigation Example</title>
<script>
document.addEventListener('DOMContentLoaded', function () {
  const links = document.querySelectorAll('a');
  let currentFocus = 0;
  links[currentFocus].focus();
  document.addEventListener('keydown', function(event) {
    if (event.key === "ArrowDown") {
      currentFocus = (currentFocus + 1) % links.length;
      links[currentFocus].focus();
      event.preventDefault();
    }
    if (event.key === "ArrowUp") {
      currentFocus = (currentFocus - 1 + links.length) % links.length;
      links[currentFocus].focus();
      event.preventDefault();
    }
  });
});
</script>
</head>
<body>
<nav>
  <a href="#home">Home</a>
  <a href="#about">About</a>
  <a href="#services">Services</a>
  <a href="#contact">Contact</a>
</nav>
<p>Use the Up and Down arrow keys to navigate between the links.</p>
</body>
</html>

Эти примеры не только демонстрируют техническую реализацию событий keydown и keyup, но и показывают их практическое применение для повышения интерактивности и доступности веб-приложений. Используя описанные возможности, разработчики могут создавать более привлекательный и инклюзивный пользовательский опыт.

Заключение

Клавиатурные события keydown и keyup незаменимы при создании динамичных и интерактивных веб-приложений. Запомните главное: keydown срабатывает (и повторяется) при нажатии, keyup срабатывает один раз при отпускании, event.key возвращает символ, а event.code — физическую клавишу; флаги модификаторов вместе с event.repeat позволяют реализовывать надёжные горячие клавиши. Приведённые примеры — отправная точка для добавления клавиатурного взаимодействия в ваши собственные проекты.

Связанные главы

Практика

Практика
Какие события JavaScript используются для обнаружения ввода с клавиатуры?
Какие события JavaScript используются для обнаружения ввода с клавиатуры?
Was this page helpful?