Как реализовать перетаскивание галереи мышью на JavaScript

    Многие современные сайты используют горизонтальные галереи миниатюр с автоматическим overflow-x. Однако стандартный скролл не всегда интуитивно понятен пользователю. Гораздо удобнее, когда миниатюры можно перетаскивать зажатой кнопкой мыши. В этой статье мы разберём готовое решение на чистом JavaScript.

    Проблема: статичный скролл вместо drag-перетаскивания

    Обычно при переполнении контейнера браузер показывает полосу прокрутки. Пользователь может крутить колёсико мыши или тащить ползунок, но это неудобно для галерей с миниатюрами. Нужно, чтобы при зажатой левой кнопке мыши и движении курсора содержимое плавно перемещалось.

    Решение: обработчики событий мыши

    Ключевая идея - отслеживать mousedown, mousemove и mouseup на контейнере с миниатюрами. В момент нажатия запоминаем начальную позицию курсора и текущее значение scrollLeft. При движении вычисляем разницу и применяем её к scrollLeft. Коэффициент ускорения (например, 3) позволяет регулировать скорость перетаскивания.

    Шаг 1. Выбор контейнера

    В вашем случае это элемент с классом .thumber .t-slds__bullet_wrapper. Если таких блоков несколько, используйте querySelectorAll и цикл.

    Шаг 2. Добавление обработчиков

    Приведённый ниже код добавляет drag-скролл для одного контейнера. Убедитесь, что контейнер имеет overflow-x: auto и white-space: nowrap (или display: flex) для горизонтального расположения миниатюр.

    const slider = document.querySelector('.thumber .t-slds__bullet_wrapper');
    let isDown = false;
    let startX;
    let scrollLeft;
    
    slider.addEventListener('mousedown', (e) => {
      isDown = true;
      slider.classList.add('active');
      startX = e.pageX - slider.offsetLeft;
      scrollLeft = slider.scrollLeft;
    });
    
    slider.addEventListener('mouseleave', () => {
      isDown = false;
      slider.classList.remove('active');
    });
    
    slider.addEventListener('mouseup', () => {
      isDown = false;
      slider.classList.remove('active');
    });
    
    slider.addEventListener('mousemove', (e) => {
      if (!isDown) return;
      e.preventDefault();
      const x = e.pageX - slider.offsetLeft;
      const walk = (x - startX) * 3;
      slider.scrollLeft = scrollLeft - walk;
    });

    Важные нюансы реализации

    • Коэффициент скорости: значение 3 можно менять - чем оно выше, тем быстрее скролл.
    • Отключение выделения текста: добавьте CSS-свойство user-select: none для контейнера, чтобы при перетаскивании не выделялись элементы.
    • Поддержка тач-событий: для мобильных устройств потребуются обработчики touchstart, touchmove, touchend.
    • Класс active: используется для визуальной обратной связи (например, изменение курсора на grabbing).

    Пример стилизации для drag-скролла

    Добавьте в CSS:

    .thumber .t-slds__bullet_wrapper {
      overflow-x: auto;
      white-space: nowrap;
      cursor: grab;
      user-select: none;
    }
    
    .thumber .t-slds__bullet_wrapper.active {
      cursor: grabbing;
    }

    Заключение

    Реализация перетаскивания галереи мышью не требует сложных библиотек - достаточно нескольких строк JavaScript. Главное - правильно выбрать контейнер и обработать события мыши. Такой подход значительно улучшает UX при просмотре большого количества миниатюр.

    Часто задаваемые вопросы