Работа с изменением ориентации экрана

Stickybits — это легковесная библиотека для реализации «липких» элементов на странице. Она позволяет закреплять DOM-элементы при прокрутке, а также управлять их поведением при изменении условий отображения, таких как размер окна и ориентация экрана. Ориентация экрана особенно важна для мобильных устройств, где смена портретного и ландшафтного режимов может менять поведение фиксированных элементов.

Детекция изменения ориентации

В JavaScript существует несколько способов отслеживать смену ориентации экрана. Stickybits напрямую не предоставляет отдельного API для этого, но его можно интегрировать с нативными событиями браузера.

window.addEventListener('orientationchange', function() {
    console.log('Ориентация экрана изменилась на: ' + window.orientation);
});
  • window.orientation возвращает угол поворота экрана:

    • 0 — портретная ориентация
    • 90 — ландшафтная ориентация по часовой стрелке
    • -90 — ландшафтная ориентация против часовой стрелки
    • 180 — перевёрнутый портрет

Инициализация Stickybits с учетом ориентации

Stickybits позволяет гибко конфигурировать поведение элементов через объект опций. Для корректной работы при смене ориентации необходимо учитывать ширину окна и повторно инициализировать sticky-элемент при изменении ориентации:

let stickyElement = document.querySelector('.sticky');
let stickyInstance = stickybits(stickyElement, {
    stickyBitStickyOffset: 20,
    useStickyClasses: true
});

window.addEventListener('orientationchange', function() {
    // Деинициализация перед повторной инициализацией
    stickyInstance.cleanup();
    
    // Переинициализация с учетом новой ширины экрана
    stickyInstance = stickybits(stickyElement, {
        stickyBitStickyOffset: 20,
        useStickyClasses: true
    });
});

Ключевой момент: метод cleanup() удаляет все обработчики и классы, назначенные библиотекой, что позволяет корректно пересоздать sticky-элемент без дублирования событий.

Адаптивное управление отступами и позиционированием

Изменение ориентации экрана часто влияет на размер доступной области контента. Stickybits предоставляет опцию stickyBitStickyOffset, которая задаёт верхний отступ для «липкого» элемента. Для динамического изменения отступа при смене ориентации можно использовать условные конструкции:

function updateStickyOffset() {
    let offset = window.innerWidth > window.innerHeight ? 40 : 20;
    stickyInstance.cleanup();
    stickyInstance = stickybits(stickyElement, {
        stickyBitStickyOffset: offset,
        useStickyClasses: true
    });
}

window.addEventListener('orientationchange', updateStickyOffset);
window.addEventListener('resize', updateStickyOffset);

Такой подход обеспечивает адаптивное поведение, при котором элемент корректно закрепляется независимо от ориентации и размеров экрана.

Использование positionSticky и fallback

Stickybits по умолчанию использует CSS-свойство position: sticky. На некоторых старых устройствах с мобильными браузерами поддержка этого свойства может быть ограничена. Для работы с ориентацией и различными браузерами рекомендуется включать fallback через JS:

stickybits('.sticky', {
    useStickyClasses: true,
    stickyBitStickyOffset: 20,
    noStyles: false // автоматически применяет fallback стили
});
  • noStyles: false позволяет Stickybits применять собственные inline-стили для закрепления элемента, что увеличивает совместимость при смене ориентации.
  • Использование useStickyClasses добавляет классы .js-is-sticky и .js-is-stuck, что позволяет дополнительно управлять стилями через CSS в зависимости от состояния элемента.

Обработка сложных макетов

При работе с многоколоночными макетами или фиксированными шапками важно учитывать, что изменение ориентации может изменить высоту родительского контейнера. Stickybits автоматически пересчитывает позицию элемента при инициализации, но при смене ориентации необходимо вручную вызвать пересчёт:

function recalcSticky() {
    stickyInstance.update(); // обновляет позицию sticky элемента
}

window.addEventListener('orientationchange', recalcSticky);
window.addEventListener('resize', recalcSticky);

Метод update() пересчитывает высоту родителя, верхний отступ и положение «липкого» элемента, что предотвращает его наложение на другие блоки.

Советы по оптимизации

  • Минимизировать частоту пересоздания sticky-элементов: использовать debounce для событий resize и orientationchange.
  • Проверять поддерживаемость position: sticky через CSS или JS перед активацией Stickybits, чтобы избежать лишней нагрузки.
  • Для элементов, закреплённых внутри scrollable контейнеров, использовать опцию parentClass для правильного расчёта границ при смене ориентации.
stickybits('.sticky', {
    stickyBitStickyOffset: 20,
    useStickyClasses: true,
    parentClass: 'sticky-parent'
});

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