Ориентация экрана

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


Слушатели событий изменения ориентации

Popper.js использует встроенные наблюдатели изменений размеров и положения, включая ResizeObserver и события window.resize. Однако, для мобильных устройств критически важно учитывать событие orientationchange. Оно возникает при повороте устройства и может существенно менять размеры области видимости.

Пример подключения слушателя:

const popperInstance = Popper.createPopper(referenceElement, popperElement, {
  placement: 'bottom',
});

window.addEventListener('orientationchange', () => {
  popperInstance.update();
});

Вызов метода update() позволяет пересчитать позиции поппера с учетом нового размера окна или ориентации. Без этого вызова всплывающий элемент может оказаться за пределами видимой области или перекрывать другие элементы интерфейса.


Использование preventOverflow для адаптивного поведения

Модуль preventOverflow предотвращает выход поппера за пределы контейнера или окна. При изменении ориентации экрана важно корректно настраивать границы ограничения.

const popperInstance = Popper.createPopper(referenceElement, popperElement, {
  modifiers: [
    {
      name: 'preventOverflow',
      options: {
        boundary: 'viewport', // можно использовать родительский элемент или документ
        altAxis: true,        // учитывает вторую ось при ограничении
      },
    },
  ],
});

Опция altAxis: true позволяет автоматически переносить элемент на противоположную сторону, если новая ориентация делает стандартное расположение неприемлемым.


Динамическое изменение placement в зависимости от ориентации

Popper.js позволяет изменять placement на лету, что особенно полезно при адаптивных интерфейсах:

function adjustPlacement() {
  const isPortrait = window.innerHeight > window.innerWidth;
  popperInstance.setOptions({
    placement: isPortrait ? 'bottom' : 'right',
  });
}

window.addEventListener('orientationchange', () => {
  adjustPlacement();
  popperInstance.update();
});

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


Модификатор flip для автоматической корректировки

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

const popperInstance = Popper.createPopper(referenceElement, popperElement, {
  modifiers: [
    {
      name: 'flip',
      options: {
        fallbackPlacements: ['top', 'right', 'left', 'bottom'],
      },
    },
  ],
});

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


Производительность при частых изменениях ориентации

На мобильных устройствах событие orientationchange может вызываться многократно при прокрутке или анимации. Чтобы снизить нагрузку на рендеринг, рекомендуется использовать дебаунсинг:

let resizeTimeout;
window.addEventListener('orientationchange', () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(() => {
    popperInstance.update();
  }, 100);
});

Это предотвращает множественные пересчеты положения поппера за короткий промежуток времени и улучшает плавность интерфейса.


Адаптация размеров поппера под новую ориентацию

Popper.js не ограничивает размеры элементов, но для динамичных интерфейсов полезно пересчитывать ширину или высоту поппера:

function resizePopper() {
  if (window.innerWidth < 600) {
    popperElement.style.width = '90%';
  } else {
    popperElement.style.width = 'auto';
  }
}

window.addEventListener('orientationchange', () => {
  resizePopper();
  popperInstance.update();
});

Комбинация изменения размеров и корректного позиционирования обеспечивает качественный пользовательский опыт на всех устройствах и ориентациях.


Отслеживание видимости целевого элемента

При изменении ориентации важно проверять, что целевой элемент (referenceElement) остаётся видимым. Модификатор preventOverflow и метод update() автоматически учитывают видимость, но для сложных интерфейсов может потребоваться ручная проверка:

function ensureReferenceVisible() {
  const rect = referenceElement.getBoundingClientRect();
  if (rect.bottom < 0 || rect.top > window.innerHeight) {
    popperElement.style.display = 'none';
  } else {
    popperElement.style.display = 'block';
    popperInstance.update();
  }
}

window.addEventListener('orientationchange', ensureReferenceVisible);

Это предотвращает появление попперов в неожиданных местах, когда целевой элемент скрыт или выходит за пределы экрана.


Popper.js сочетает мощные возможности управления позиционированием с гибкими модификаторами, позволяя адаптировать всплывающие элементы под любые ориентации экрана и размеры устройства. Использование слушателей событий, динамического изменения placement, модификаторов flip и preventOverflow обеспечивает корректное отображение интерфейсных компонентов в любых условиях.