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 обеспечивает корректное
отображение интерфейсных компонентов в любых условиях.