Библиотека Noty изначально ориентирована на кросс-платформенное использование, включая мобильные устройства. Для этого в ней предусмотрена встроенная поддержка тач-событий, позволяющая управлять уведомлениями с помощью жестов: свайпов, касаний и удержаний.
В основе лежит использование стандартных событий браузера:
touchstarttouchmovetouchendNoty автоматически отслеживает эти события для каждого уведомления и применяет их для реализации интерактивного поведения.
Ключевые задачи:
При касании уведомления фиксируется начальная точка
(touchstart). Далее при перемещении
(touchmove) вычисляется смещение по оси X. Если
пользователь отпускает палец (touchend) и смещение
превышает заданный порог — уведомление закрывается.
let startX = 0;
let currentX = 0;
element.addEventListener('touchstart', (e) => {
startX = e.touches[0].clientX;
});
element.addEventListener('touchmove', (e) => {
currentX = e.touches[0].clientX;
let diff = currentX - startX;
element.style.transform = `translateX(${diff}px)`;
});
element.addEventListener('touchend', () => {
let diff = currentX - startX;
if (Math.abs(diff) > 100) {
closeNotification();
} else {
element.style.transform = 'translateX(0)';
}
});
В Noty аналогичная логика встроена и не требует ручной реализации.
closeWithОпределяет способы закрытия уведомления.
new Noty({
text: 'Уведомление',
closeWith: ['click', 'button']
}).show();
Хотя свайпы не указываются явно, они активны по умолчанию на мобильных устройствах.
timeoutАвтоматическое закрытие может конфликтовать с жестами.
timeout: false
Отключение таймера даёт пользователю больше времени для взаимодействия.
animationАнимации влияют на восприятие жестов.
animation: {
open: 'animated fadeIn',
close: 'animated fadeOut'
}
При использовании свайпов желательно избегать слишком долгих анимаций закрытия.
Минимальное расстояние свайпа должно быть достаточно большим, чтобы избежать случайных закрытий, но не слишком большим, чтобы не усложнять взаимодействие.
Типичное значение: 80–120 пикселей.
Во время свайпа Noty сдвигает уведомление вслед за пальцем. Это создаёт ощущение «физического» взаимодействия.
Дополнительно можно:
Чаще всего используется горизонтальный свайп:
Вертикальные жесты обычно игнорируются, чтобы не конфликтовать с прокруткой страницы.
Хотя Noty не предоставляет прямого API для настройки touch-событий, возможно вмешательство через DOM.
let n = new Noty({ text: 'Пример' }).show();
n.on('afterShow', function() {
let el = n.barDom;
el.addEventListener('touchstart', customHandler);
});
el.addEventListener('touchmove', (e) => {
let diff = e.touches[0].clientX - startX;
if (diff < 0) {
el.style.transform = `translateX(${diff}px)`;
}
});
Noty ориентирован на одиночные касания (single touch).
При наличии нескольких точек касания:
Рекомендуется фильтровать:
if (e.touches.length > 1) return;
preventDefault() в некоторых случаяхpassive: true)Для повышения производительности:
element.addEventListener('touchmove', handler, { passive: true });
Однако:
preventDefault()При вертикальном скролле страницы возможны ложные срабатывания.
Решение:
let diffX = Math.abs(currentX - startX);
let diffY = Math.abs(currentY - startY);
if (diffY > diffX) {
// считаем это скроллом, а не свайпом
return;
}
Современная альтернатива touch-событиям — Pointer Events:
pointerdownpointermovepointerupПреимущества:
Noty по умолчанию использует классические touch-события, но возможно расширение:
element.addEventListener('pointerdown', handler);
Во время взаимодействия важно отслеживать состояние:
isDraggingstartPositioncurrentPositionЭто предотвращает:
Частые события touchmove могут нагружать интерфейс.
Оптимизации:
requestAnimationFrameПример:
let ticking = false;
element.addEventListener('touchmove', (e) => {
if (!ticking) {
requestAnimationFrame(() => {
updatePosition(e);
ticking = false;
});
ticking = true;
}
});
Для сложных сценариев:
Это позволяет реализовать: