Заметки кодящего дизайнера

Отслеживание нажатия клавиш

Про клавиатурные события и отслеживание нажатий клавиш, как одиночных, так и шорткатов.

Для работы с клавиатурой надо запомнить два события:

  • keydown — нажатие клавиши (включая удерживание).
  • keyup — срабатывает при отпускании клавиши.

Раньше ещё было keypress, но оно устарело.

Отследить одиночное нажатие

Для примера возьму наиболее распространённый в моей практике кейс — отслеживание нажатия клавиши Escape (например, чтобы закрыть модалку).

document.addEventListener('keydown', function(event) {
    if (event.key === 'Escape' || event.key === 'Esc') {
        console.log('Escape key pressed!');
        // Код для обработки нажатия клавиши Escape
    }
});

Отследить комбинацию клавиш

Например, в админке одного сайта мне захотелось по нажатию комбинации cmd + s сохранять изменения в записи.

// Функция для примера
const saveDocument = () => {
    console.log('Документ сохранен!');
}

document.addEventListener('keydown', function(event) {
    const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; // Проверка платформы

    // Проверяем комбинацию клавиш
    if ((isMac && event.metaKey && event.key === 's') || 
        (!isMac && event.ctrlKey && event.key === 's')) {
        event.preventDefault(); // Останавливаем стандартное поведение (сохранение страницы)
        console.log('Комбинация Cmd + S или Ctrl + S нажата');
        
        // Ваш код
        saveDocument(); // Вызов функции сохранения
    }
});

Двойное нажатие

А вот ещё один кейс. Мне понадобилось лично для себя добавить скрытую фичу, которая снимает фокус с активного элемента при двойном нажатии Escape. Сделал это так.

let lastEscapePressTime = 0; // Создаём переменную для хранения времени последнего нажатия

const removeFocusOnDoubleEscape = () => {
    document.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' || event.key === 'Esc') {
            const currentTime = Date.now();

            // Проверяем, было ли предыдущее нажатие Escape недавно
            if (currentTime - lastEscapePressTime <= 300) { // 300 мс — интервал между нажатиями
                // Снимаем фокус со всех элементов
                document.activeElement.blur();
            }

            lastEscapePressTime = currentTime; // Обновляем время последнего нажатия
        }
    });
};