Sticky Elements

Sticky-элементы позволяют закреплять блоки на экране при прокрутке страницы, создавая эффект «прилипшего» контента. В сочетании с библиотекой Waypoints это даёт мощный инструмент для управления поведением элементов при скролле. Waypoints предоставляет простой способ отслеживания положения элементов относительно окна просмотра и запуска функций при пересечении определённых точек.

Принцип работы: Waypoints создаёт «точки останова» (waypoints) для выбранных элементов. Когда верхняя или нижняя граница элемента достигает определённой позиции на странице (по умолчанию — верх окна), вызывается заданная функция. Для sticky-элементов это обычно используется для добавления или удаления CSS-класса с position: sticky или position: fixed.

var stickyElement = document.querySelector('.sticky');

var waypoint = new Waypoint({
  element: stickyElement,
  handler: function(direction) {
    if(direction === 'down') {
      stickyElement.classList.add('is-sticky');
    } else {
      stickyElement.classList.remove('is-sticky');
    }
  },
  offset: '0%'
});

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

  • element — DOM-элемент, за которым следит Waypoint.
  • handler — функция, вызываемая при пересечении точки. Параметр direction указывает направление прокрутки (down или up).
  • offset — позиция относительно окна, при которой срабатывает waypoint. Может быть в пикселях или процентах от высоты окна.

Настройка смещения и множественных точек

Offset позволяет точно контролировать, когда элемент становится «прилипшим». Например, если нужно, чтобы элемент активировался не сразу при входе в верхнюю часть окна, а чуть ниже:

var waypoint = new Waypoint({
  element: stickyElement,
  handler: function(direction) {
    stickyElement.classList.toggle('is-sticky', direction === 'down');
  },
  offset: '100px'
});

Для сложных интерфейсов можно создавать несколько waypoint-ов для одного элемента, чтобы управлять его поведением при разных позициях скролла:

var startSticky = new Waypoint({
  element: stickyElement,
  handler: function(direction) {
    if(direction === 'down') stickyElement.classList.add('is-sticky');
  },
  offset: '50%'
});

var stopSticky = new Waypoint({
  element: stickyElement,
  handler: function(direction) {
    if(direction === 'up') stickyElement.classList.remove('is-sticky');
  },
  offset: '-50%'
});

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

Адаптация к разным размерам экрана

Sticky-элементы требуют особого внимания при адаптивной верстке. Waypoints позволяет пересоздавать waypoint-и при изменении размеров окна, чтобы offset корректно соответствовал новому размеру:

var waypoint;

function createWaypoint() {
  if(waypoint) waypoint.destroy();

  waypoint = new Waypoint({
    element: stickyElement,
    handler: function(direction) {
      stickyElement.classList.toggle('is-sticky', direction === 'down');
    },
    offset: window.innerWidth < 768 ? '20px' : '0%'
  });
}

window.addEventListener('resize', createWaypoint);
createWaypoint();

Особенности:

  • destroy() удаляет waypoint и снимает все обработчики.
  • Пересоздание waypoint-а при ресайзе обеспечивает корректное поведение на мобильных устройствах и больших экранах.

Интеграция с анимациями и переходами

Sticky-элементы часто комбинируются с CSS-анимациями для плавного появления и скрытия:

.sticky {
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.sticky.is-sticky {
  transform: translateY(0);
  opacity: 1;
}

.sticky:not(.is-sticky) {
  transform: translateY(-10px);
  opacity: 0;
}
var waypoint = new Waypoint({
  element: stickyElement,
  handler: function(direction) {
    stickyElement.classList.toggle('is-sticky', direction === 'down');
  },
  offset: '0%'
});

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

Контроль при пересечении других элементов

Waypoints позволяет учитывать пересечение с другими элементами страницы. Например, sticky-элемент может переставать быть фиксированным при достижении футера:

var footer = document.querySelector('.footer');

var stopAtFooter = new Waypoint({
  element: footer,
  handler: function(direction) {
    if(direction === 'down') {
      stickyElement.classList.remove('is-sticky');
    } else {
      stickyElement.classList.add('is-sticky');
    }
  },
  offset: '100%'
});

Такое решение предотвращает наложение закреплённого блока на футер, сохраняя чистоту интерфейса.

Использование контекста и группы

Waypoints поддерживает контексты и группы, что полезно для страниц с несколькими скролл-блоками. Контекст позволяет отслеживать скролл в определённой области, а группы — синхронизировать обработку нескольких waypoint-ов:

var context = document.querySelector('.scrollable-area');

var waypoint = new Waypoint({
  element: stickyElement,
  handler: function(direction) {
    stickyElement.classList.toggle('is-sticky', direction === 'down');
  },
  offset: '0%',
  context: context
});

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

Поддержка динамического контента

Если контент на странице загружается динамически (например, через AJAX), нужно пересоздавать waypoint-и после вставки новых элементов:

function initStickyElements() {
  document.querySelectorAll('.sticky').forEach(function(el) {
    new Waypoint({
      element: el,
      handler: function(direction) {
        el.classList.toggle('is-sticky', direction === 'down');
      },
      offset: '0%'
    });
  });
}

// После загрузки контента
initStickyElements();

Это гарантирует, что новые sticky-элементы корректно реагируют на прокрутку.


Использование Waypoints с sticky-элементами позволяет создавать сложные интерактивные интерфейсы с контролем поведения блоков при прокрутке, точной настройкой триггеров, адаптацией к разным экранам и интеграцией с анимациями. Такой подход значительно расширяет возможности стандартного CSS position: sticky.