Прокрутка внутри контейнеров

Interact.js предоставляет мощный механизм для работы с интерактивными элементами на странице, включая перетаскивание, изменение размера и жесты. Одной из часто востребованных возможностей является автоматическая прокрутка контейнеров при перетаскивании элементов, чтобы пользователи могли перемещать объекты за пределы видимой области без ручного скролла.


Включение автопрокрутки

Для реализации автопрокрутки используется параметр autoScroll в настройках draggable объекта. Этот параметр может быть задан как булево значение или объект с конфигурацией:

interact('.draggable')
  .draggable({
    autoScroll: {
      container: document.querySelector('.scrollable-container'),
      margin: 50,
      speed: 400,
    }
  });
  • container — DOM-элемент, внутри которого будет происходить прокрутка. Если не указан, по умолчанию используется window.
  • margin — расстояние в пикселях от края контейнера, при достижении которого активируется прокрутка.
  • speed — скорость прокрутки в пикселях за секунду.

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


Настройка направления и скорости

Параметр autoScroll поддерживает более детальные настройки:

autoScroll: {
  container: document.querySelector('.scrollable-container'),
  margin: 50,
  speed: 300,
  interval: 10
}
  • interval — время в миллисекундах между шагами прокрутки. Чем меньше значение, тем плавнее движение.
  • Скорость прокрутки (speed) может быть увеличена для больших контейнеров или уменьшена для точного управления.

Если необходимо ограничить прокрутку только по горизонтали или вертикали, можно комбинировать overflow-x и overflow-y на контейнере вместе с кастомной логикой в событии dragmove.


Интеграция с событием dragmove

Автопрокрутка работает в связке с событием dragmove, что позволяет синхронизировать позицию перетаскиваемого элемента с прокруткой:

interact('.draggable')
  .draggable({
    autoScroll: { container: document.querySelector('.scrollable-container') }
  })
  .on('dragmove', function (event) {
    const target = event.target;
    const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
    const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

    target.style.transform = `translate(${x}px, ${y}px)`;
    target.setAttribute('data-x', x);
    target.setAttribute('data-y', y);
  });

Автопрокрутка автоматически смещает контейнер, если курсор подходит к его краю, а dragmove обновляет координаты элемента. Такой подход обеспечивает плавное и предсказуемое поведение при перетаскивании внутри больших областей.


Прокрутка нескольких контейнеров

Если на странице есть несколько вложенных прокручиваемых элементов, autoScroll можно настраивать для каждого контейнера отдельно:

interact('.draggable')
  .draggable({
    autoScroll: [
      { container: document.querySelector('.scrollable-container1'), margin: 40, speed: 300 },
      { container: document.querySelector('.scrollable-container2'), margin: 30, speed: 200 }
    ]
  });

Interact.js при этом автоматически определяет, к какому контейнеру ближе курсор, и прокручивает соответствующий блок.


Ограничения и оптимизация

  1. Производительность: Для больших DOM-деревьев рекомендуется уменьшить значение interval и speed, чтобы не перегружать рендеринг.
  2. Плавность: Использование CSS-свойства scroll-behavior: smooth; на контейнере делает движение более естественным, но может конфликтовать с быстрым обновлением позиции при dragmove.
  3. Контроль за границами: Автопрокрутка не позволяет элементу выйти за пределы контейнера, если задать ограничение через restrict:
interact('.draggable')
  .draggable({
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent',
        endOnly: true
      })
    ],
    autoScroll: true
  });

Это гарантирует, что элемент останется в пределах видимой области, даже если прокрутка продолжается.


Поддержка мобильных устройств

На сенсорных устройствах автопрокрутка также работает, но важно учитывать размеры сенсорной зоны и скорость движения пальца. Оптимальные значения для margin находятся в диапазоне 30–70 px. Для плавного взаимодействия с тачскрином рекомендуется тестировать одновременно с inertia, чтобы элементы не “выпрыгивали” из контейнера.


Рекомендации по дизайну

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

Автопрокрутка Interact.js сочетает в себе точное управление, высокую производительность и гибкость настройки, позволяя создавать сложные интерфейсы с перетаскиванием внутри любых прокручиваемых областей.