В Popper.js модификаторы представляют собой объекты, которые позволяют настраивать поведение поппера — позиционирование, смещение, ограничения и многие другие аспекты. Каждый модификатор выполняет определённую функцию и имеет строго определённую структуру.
Модификаторы применяются через массив modifiers, который
передается при создании экземпляра поппера:
const popperInstance = Popper.createPopper(referenceElement, popperElement, {
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8]
}
}
]
});
Каждый модификатор — это объект с несколькими обязательными и опциональными полями:
name Уникальное имя модификатора.
Обязательно для идентификации. Например: 'offset',
'flip', 'preventOverflow'.
enabled Булево значение,
определяющее, активен ли модификатор. По умолчанию
true.
phase Фаза жизненного цикла
поппера, на которой модификатор выполняется. Возможные значения:
beforeReadreadafterReadbeforeMainmainafterMainbeforeWritewriteafterWriteВажно: корректное указание фазы обеспечивает правильный порядок исполнения, что критично для сложных взаимодействий нескольких модификаторов.
requires Массив имён модификаторов,
которые должны выполниться до данного. Используется для управления
зависимостями. Например, flip требует выполнения
preventOverflow.
requiresIfExists Похож на
requires, но зависимость необязательна — модификатор
выполнится даже если указанные модификаторы отсутствуют.
options Настройки, специфичные для
модификатора. Например, у offset это массив
[skidding, distance], а у preventOverflow —
объект с полями mainAxis, altAxis и
boundary.
fn Основная функция модификатора.
Принимает объект с текущим состоянием поппера и возвращает
изменения:
function fn({ state, options, name }) {
// state содержит данные о позиционировании, размерах и элементах
// options — пользовательские настройки модификатора
// name — имя модификатора
}
effect (опционально) Функция
для установки побочных эффектов, например добавления слушателей событий.
Возвращает функцию очистки (cleanup), вызываемую при
уничтожении поппера или отключении модификатора.effect({ state, instance, options }) {
const handleResize = () => instance.update();
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}
Модификаторы выполняются в строгом порядке, определяемом их фазами и зависимостями:
Чтение данных (read) Модификаторы
на этих фазах получают текущие размеры и положение элементов,
рассчитывают необходимые параметры.
Основные вычисления (main)
Производятся расчёты с учетом offset, boundaries, flip и других
параметров.
Запись (write) Модификаторы
записывают результат вычислений в DOM, изменяя стиль и положение
поппера.
Эффекты (effect) Инициализация
событий, подписок и других побочных действий.
offset — смещение поппера относительно
reference.flip — автоматически переворачивает
поппер, если он выходит за границы контейнера.preventOverflow — предотвращает выход
поппера за границы контейнера.arrow — позиционирует стрелку
поппера.computeStyles — задаёт стили
transform и top/left для корректного
рендеринга.Каждый встроенный модификатор следует той же структуре, что и пользовательский.
Создание собственного модификатора позволяет реализовать уникальные сценарии позиционирования:
const customModifier = {
name: 'logPosition',
enabled: true,
phase: 'afterWrite',
fn({ state }) {
console.log('Popper position:', state.styles.popper);
}
};
Добавление его в массив modifiers позволит отслеживать
положение поппера после всех вычислений и записи в DOM.
requires при
зависимостях, чтобы гарантировать правильный порядок.fn должна только вычислять данные, побочные действия — в
effect.fn — избегать тяжелых
синхронных операций в фазе main, чтобы не снижать
производительность.При сложных сценариях важно понимать, что:
state, который передается
всем последующим модификаторам.state одного модификатора могут повлиять на
все остальные.Эта структура делает Popper.js гибким инструментом для любых задач позиционирования, от простых тултипов до сложных всплывающих меню и модальных окон.