DOM события клавиатуры и мыши

События клавиатуры и мыши — это механизм, позволяющий JavaScript реагировать на действия пользователя: нажатия клавиш, клики, наведение курсора и прокрутку.

Зачем нужно

Без обработки этих событий страница остаётся статичной. Именно через события клавиатуры и мыши реализуются интерактивные элементы: выпадающие меню, модальные окна, горячие клавиши, drag-and-drop, игровая логика и доступные компоненты. Понимание порядка событий (mousedown → mouseup → click) помогает избежать трудноуловимых багов.

Где используется

  • Кнопки и ссылки (обработка click)
  • Горячие клавиши и сочетания (Ctrl+S, Escape, Enter)
  • Выпадающие меню (закрытие по клику вне, по Escape)
  • Tooltip и hover-эффекты (mouseenter / mouseleave)
  • Игровые интерфейсы (движение персонажа по keydown)
  • Перетаскивание элементов (drag-and-drop через mouse-события)

Основной контент

Добавление обработчика

const btn = document.querySelector('#myBtn');

btn.addEventListener('click', (event) => {
  console.log('Клик!', event);
});

// Удаление — нужна именованная функция
function handleClick(e) { console.log('click'); }
btn.addEventListener('click', handleClick);
btn.removeEventListener('click', handleClick);

События мыши

Событие Когда срабатывает
click Нажатие и отпускание левой кнопки
dblclick Двойной клик
mousedown Кнопка мыши нажата
mouseup Кнопка мыши отпущена
mousemove Курсор движется
mouseenter Курсор вошёл в элемент (не всплывает)
mouseleave Курсор покинул элемент (не всплывает)
mouseover Курсор над элементом или потомком (всплывает)
contextmenu Правый клик / клавиша контекстного меню
const card = document.querySelector('.card');

card.addEventListener('mouseenter', () => card.classList.add('hovered'));
card.addEventListener('mouseleave', () => card.classList.remove('hovered'));

card.addEventListener('mousemove', (e) => {
  console.log(`Позиция: ${e.clientX}, ${e.clientY}`);
});

Координаты мыши

document.addEventListener('click', (e) => {
  e.clientX;   // от левого края viewport
  e.clientY;   // от верхнего края viewport
  e.pageX;     // от начала страницы (с учётом прокрутки)
  e.pageY;
  e.offsetX;   // от левого края целевого элемента
  e.offsetY;
});

События клавиатуры

Событие Когда срабатывает
keydown Клавиша нажата (повторяется при удержании)
keyup Клавиша отпущена
keypress Устаревшее, не используйте
document.addEventListener('keydown', (e) => {
  console.log(e.key);      // 'Enter', 'Escape', 'a', 'ArrowLeft'
  console.log(e.code);     // 'KeyA', 'Digit1', 'Space' (раскладка не влияет)
  console.log(e.ctrlKey);  // true если Ctrl зажат
  console.log(e.shiftKey);
  console.log(e.altKey);
  console.log(e.metaKey);  // Cmd на Mac

  if (e.key === 'Escape') closeModal;
  if (e.ctrlKey && e.key === 's') { e.preventDefault(); save; }
});

Делегирование событий

// Один обработчик на список вместо обработчика на каждый элемент
const list = document.querySelector('ul');

list.addEventListener('click', (e) => {
  const item = e.target.closest('li');
  if (!item) return;
  console.log('Клик на:', item.textContent);
});

Прокрутка и колесо мыши

window.addEventListener('scroll', () => {
  console.log(window.scrollY);
});

el.addEventListener('wheel', (e) => {
  e.deltaY; // направление прокрутки колеса
});

Частые ошибки

  • Используют e.keyCode или e.which — оба устарели. Используйте e.key для символа или e.code для физической клавиши.
  • Вешают обработчик на каждый элемент в цикле — при большом количестве элементов это перегружает память. Используйте делегирование.
  • Путают mouseenter и mouseovermouseover всплывает и срабатывает при наведении на потомков; mouseenter срабатывает только для самого элемента.
  • Не вызывают e.preventDefault() — для ссылок, кнопок отправки форм и горячих клавиш браузера нужно явно отменять поведение по умолчанию.

Связанные темы

Ресурсы