Обработка событий клавиатуры и мыши

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


События мыши

События мыши в Hyperapp обрабатываются через атрибуты компонентов, аналогично стандартному HTML, но с привязкой к функциям действий (actions). Наиболее часто используемые события:

  • onclick — клик мыши
  • ondblclick — двойной клик
  • onmousedown / onmouseup — нажатие и отпускание кнопки мыши
  • onmousemove — движение мыши
  • onmouseenter / onmouseleave — наведение и уход курсора

Пример использования:

import { h, app } from "hyperapp";

const state = { count: 0 };

const actions = {
  increment: () => state => ({ count: state.count + 1 }),
  decrement: () => state => ({ count: state.count - 1 })
};

const view = (state, actions) => (
  h("div", {}, [
    h("button", { onclick: actions.increment }, "Увеличить"),
    h("button", { onclick: actions.decrement }, "Уменьшить"),
    h("p", {}, `Текущее значение: ${state.count}`)
  ])
);

app({ init: state, view, actions });

В этом примере нажатие кнопок вызывает соответствующие действия, изменяющие состояние. События мыши передают объект события в функцию действия, если это необходимо:

onclick: (event) => actions.handleClick(event)

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


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

Для клавиатурных событий Hyperapp использует стандартные DOM-события: onkeydown, onkeyup, onkeypress. Основное отличие в том, что обработчик принимает объект события, позволяя реагировать на конкретные клавиши.

Пример обработки нажатия клавиш:

const state = { message: "" };

const actions = {
  updateMessage: (event) => state => ({ message: state.message + event.key })
};

const view = (state, actions) => (
  h("input", { 
    onkeydown: actions.updateMessage, 
    value: state.message 
  })
);

app({ init: state, view, actions });

В этом примере каждое нажатие клавиши добавляется к строке состояния message. В объекте события доступны такие свойства, как:

  • key — символ клавиши
  • code — физическая клавиша на клавиатуре
  • altKey, ctrlKey, shiftKey, metaKey — состояния модификаторов

Использование этих свойств позволяет создавать комбинации клавиш и более сложную логику управления.


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

Hyperapp поддерживает декларативный стиль, что делает код чистым и читаемым. Вместо привязки событий после создания элементов через addEventListener, все события задаются сразу в функции view. Это упрощает управление состоянием и минимизирует побочные эффекты.

Пример сочетания событий мыши и клавиатуры:

const state = { color: "black" };

const actions = {
  changeColor: (color) => () => ({ color })
};

const view = (state, actions) => (
  h("div", { 
    onkeydown: (e) => e.key === "r" && actions.changeColor("red")(),
    onmousedown: () => actions.changeColor("blue")(),
    tabindex: 0, // делает div фокусируемым для клавиатуры
    style: { width: "200px", height: "200px", backgroundColor: state.color }
  })
);

Ключевой момент — использование tabindex, чтобы элемент мог принимать фокус и реагировать на клавиатурные события.


Совмещение событий с асинхронными действиями

Hyperapp позволяет комбинировать обработку событий с асинхронными операциями, например, загрузкой данных или задержкой:

const actions = {
  fetchData: () => async state => {
    const response = await fetch("https://api.example.com/data");
    const data = await response.json();
    return { data };
  }
};

const view = (state, actions) => (
  h("button", { onclick: actions.fetchData }, "Загрузить данные")
);

Асинхронные действия интегрируются в стандартный поток обработки событий, не нарушая реактивность приложения.


Важные рекомендации

  • Все функции действий должны возвращать новое состояние или объект изменений. Изменение состояния напрямую запрещено.
  • Для элементов, которые должны принимать клавиатурный фокус, необходимо использовать tabindex.
  • При работе с событиями мыши часто важно предотвращать стандартное поведение (event.preventDefault()), чтобы избежать нежелательных эффектов браузера.
  • Использование деструктуризации объекта события упрощает чтение кода: const { key, altKey } = event;.

Расширенные возможности

Hyperapp позволяет создавать кастомные события и комбинировать их с существующими, что дает возможность строить сложные интерактивные интерфейсы без использования внешних библиотек. Например, можно отслеживать двойные клики и удержание клавиши Shift для специальных действий.

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