Фреймворк Fresh построен на базе Deno и ориентирован на современный подход к рендерингу веб-приложений с минимальным использованием клиентского JavaScript. Работа с сенсорными событиями (Touch events) в Fresh требует понимания как серверной, так и клиентской частей, так как обработка событий происходит преимущественно на клиенте, но может быть интегрирована с серверной логикой через сигналы и состояния компонентов.
В JavaScript существуют стандартные события для сенсорных экранов:
touchstart — возникает при касании
элемента пальцем.touchmove — срабатывает при
перемещении пальца по экрану.touchend — вызывается при отпускании
пальца.touchcancel — срабатывает, когда
система прерывает сенсорное взаимодействие (например, входящий звонок на
мобильном устройстве).Каждое из этих событий содержит объект TouchEvent,
который включает массив touches (все активные касания),
targetTouches (касания на конкретном элементе) и
changedTouches (касания, изменившие состояние в текущем
событии).
Fresh использует islands architecture, что позволяет привязывать интерактивные компоненты с минимальным JavaScript. Для работы с сенсорными событиями создаются клиентские компоненты:
/** @jsx h */
import { h } from "preact";
import { useState } from "preact/hooks";
export default function TouchTracker() {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleTouchMove = (e) => {
const touch = e.touches[0];
setPosition({ x: touch.clientX, y: touch.clientY });
};
return (
<div
onTouchM ove={handleTouchMove}
style={{
width: "100vw",
height: "100vh",
backgroundColor: "#f0f0f0",
touchAction: "none",
}}
>
<p>Координаты: {position.x}, {position.y}</p>
</div>
);
}
Ключевые моменты:
touchAction: "none" — отключает стандартное поведение
браузера при свайпах и масштабировании, позволяя полностью
контролировать жесты.useState для отслеживания координат
позволяет обновлять интерфейс в реальном времени без перезагрузки
страницы.onTouchMove привязывается напрямую к элементу DOM, что
обеспечивает нативное реагирование на события.Для поддержки нескольких пальцев необходимо использовать массив
touches. Пример отслеживания двух касаний одновременно:
const handleMultiTouch = (e) => {
if (e.touches.length >= 2) {
const touch1 = e.touches[0];
const touch2 = e.touches[1];
const distance = Math.hypot(
touch2.clientX - touch1.clientX,
touch2.clientY - touch1.clientY
);
console.log("Расстояние между пальцами:", distance);
}
};
Использование этого подхода позволяет реализовать жесты pinch-to-zoom или multi-finger swipe без сторонних библиотек.
Fresh позволяет использовать server-side rendering вместе с интерактивными компонентами. Для передачи данных о касаниях на сервер можно использовать:
Пример передачи координат на сервер:
const sendPosition = async (x, y) => {
await fetch("/api/touch", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ x, y }),
});
};
const handleTouchMove = (e) => {
const touch = e.touches[0];
sendPosition(touch.clientX, touch.clientY);
};
На серверной стороне можно использовать API routes Fresh для обработки POST-запросов.
При работе с touch-событиями важно учитывать производительность:
preventDefault().touchmove) с помощью
requestAnimationFrame или
дебаунсинга.Пример с requestAnimationFrame:
let ticking = false;
const handleTouchMove = (e) => {
if (!ticking) {
window.requestAnimationFrame(() => {
const touch = e.touches[0];
setPosition({ x: touch.clientX, y: touch.clientY });
ticking = false;
});
ticking = true;
}
};
touch-action позволяет
предотвратить это.События touchstart, touchmove и
touchend можно комбинировать с
pointer-событиями (pointerdown,
pointermove) для создания универсальных интерфейсов,
работающих как на десктопе, так и на мобильных устройствах. В Fresh это
удобно реализуется через Preact-хуки и props компонентов.
Система Touch events в Fresh предоставляет мощный инструмент для создания интерактивных мобильных интерфейсов с минимальной нагрузкой на клиентский код, позволяя одновременно использовать серверную обработку и современные возможности браузеров.