Определение направления свайпа

Zepto.js — это компактная библиотека JavaScript, ориентированная на работу с DOM, событиями и анимацией, предоставляющая упрощённый синтаксис, аналогичный jQuery. Одной из задач при работе с мобильными интерфейсами является определение направления свайпа — движения пальца по экрану влево, вправо, вверх или вниз.

Основные концепции

Свайп реализуется через обработку последовательности событий touchstart, touchmove и touchend:

  • touchstart — фиксирует начальную точку касания.
  • touchmove — позволяет отслеживать изменение координат касания в реальном времени.
  • touchend — фиксирует конечную точку и позволяет вычислить направление движения.

Для корректного определения направления важно учитывать разницу координат по оси X и Y, а также минимальное расстояние движения (threshold), чтобы случайные касания не трактовались как свайпы.

Фиксация начальной точки

var startX, startY;

$(document).on('touchstart', function(event) {
    var touch = event.touches ? event.touches[0] : event;
    startX = touch.pageX;
    startY = touch.pageY;
});

Пояснение: touches[0] содержит информацию о первом касании. Свойства pageX и pageY дают координаты относительно страницы.

Отслеживание движения

Для определения направления движения нужно фиксировать конечные координаты при завершении касания. Событие touchmove можно использовать для визуальной обратной связи, но для простого определения направления достаточно touchend:

$(document).on('touchend', function(event) {
    var touch = event.changedTouches ? event.changedTouches[0] : event;
    var endX = touch.pageX;
    var endY = touch.pageY;

    var deltaX = endX - startX;
    var deltaY = endY - startY;
    
    var threshold = 30; // минимальное смещение для свайпа

    if (Math.abs(deltaX) > Math.abs(deltaY)) {
        if (Math.abs(deltaX) > threshold) {
            if (deltaX > 0) {
                console.log('Свайп вправо');
            } else {
                console.log('Свайп влево');
            }
        }
    } else {
        if (Math.abs(deltaY) > threshold) {
            if (deltaY > 0) {
                console.log('Свайп вниз');
            } else {
                console.log('Свайп вверх');
            }
        }
    }
});

Ключевые моменты:

  • Math.abs(deltaX) > Math.abs(deltaY) определяет, что движение больше горизонтальное, чем вертикальное.
  • threshold защищает от ложных срабатываний при небольших смещениях.

Создание собственного плагина Zepto для свайпов

Zepto позволяет расширять функционал с помощью методов $.fn. Создание собственного метода swipe делает код более универсальным:

$.fn.swipe = function(callback, threshold = 30) {
    return this.each(function() {
        var startX, startY;

        $(this).on('touchstart', function(event) {
            var touch = event.touches ? event.touches[0] : event;
            startX = touch.pageX;
            startY = touch.pageY;
        });

        $(this).on('touchend', function(event) {
            var touch = event.changedTouches ? event.changedTouches[0] : event;
            var deltaX = touch.pageX - startX;
            var deltaY = touch.pageY - startY;
            var direction = null;

            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                if (Math.abs(deltaX) > threshold) {
                    direction = deltaX > 0 ? 'right' : 'left';
                }
            } else {
                if (Math.abs(deltaY) > threshold) {
                    direction = deltaY > 0 ? 'down' : 'up';
                }
            }

            if (direction) callback.call(this, direction);
        });
    });
};

Применение:

$('#swipeArea').swipe(function(direction) {
    console.log('Свайп: ' + direction);
});

Дополнительные рекомендации

  1. Стабильность на разных устройствах: Разные устройства могут давать разные значения pageX/pageY при масштабировании страницы. В сложных проектах можно учитывать clientX/clientY и scrollOffset.

  2. Обработка нескольких касаний: Если требуется поддержка мультитача, необходимо отслеживать массив event.touches и идентификаторы touch.identifier.

  3. Оптимизация производительности: Не рекомендуется обрабатывать события touchmove на каждом пикселе движения. Для динамических интерфейсов достаточно использовать requestAnimationFrame или фиксированные интервалы.

  4. Совместимость с мышью: Для десктопных версий можно добавить обработку событий mousedown и mouseup с той же логикой вычисления направления.

Преимущества использования Zepto

  • Лёгкий размер библиотеки ускоряет загрузку страниц.
  • Поддержка мобильных событий напрямую через on и off.
  • Удобное расширение через плагины ($.fn).
  • Единый синтаксис для работы с DOM, CSS и событиями.

Определение направления свайпа с помощью Zepto позволяет создавать плавные, отзывчивые интерфейсы на мобильных устройствах без привлечения тяжёлых библиотек. Ключевыми аспектами остаются точная фиксация начальной и конечной точки, минимальная дистанция для распознавания и корректная обработка осей X и Y.