Popper.js использует модификаторы для управления позиционированием элементов. Каждый модификатор выполняет отдельную задачу: смещает, ограничивает или изменяет ориентацию поппера. Важным аспектом является правильное управление зависимостями между модификаторами, поскольку порядок их выполнения напрямую влияет на итоговое поведение поппера.
Модификатор может зависеть от результатов другого
модификатора. Например, модификатор flip
проверяет, хватает ли места для отображения поппера. Он должен
выполняться после модификатора
preventOverflow, который ограничивает выход поппера за
границы видимой области.
Зависимости задаются через поле
requires. Каждому модификатору можно определить
массив других модификаторов, которые должны быть выполнены до
него:
{
name: 'flip',
enabled: true,
phase: 'main',
requires: ['preventOverflow']
}
В этом примере flip будет запускаться только после
успешного применения preventOverflow.
phase) определяет момент,
когда модификатор применяется. Модификаторы выполняются в
следующих фазах: beforeRead, read,
afterRead, beforeMain, main,
afterMain, beforeWrite, write,
afterWrite. Если модификатор зависит от другого, важно
согласовать их фазы: зависимый модификатор должен находиться в
той же фазе или позже.offset и
preventOverflow Модификатор offset
смещает поппер относительно reference-элемента. Если одновременно
применяется preventOverflow, важно, чтобы сначала
выполнялся offset, а затем preventOverflow,
чтобы корректно ограничить поппер внутри границ.
flip и preventOverflow
Модификатор flip ориентируется на доступное пространство.
Если preventOverflow ограничивает поппер раньше,
flip будет корректно определять сторону для
переворота.
arrow и offset
Модификатор arrow отвечает за позиционирование стрелки
поппера. Чтобы стрелка правильно отображалась, необходимо сначала
вычислить смещение поппера через offset.
requiresIfExistsPopper.js позволяет использовать requiresIfExists для
необязательных зависимостей:
{
name: 'arrow',
enabled: true,
phase: 'main',
requiresIfExists: ['offset']
}
Это означает, что если модификатор offset присутствует,
он должен выполняться до arrow. Если offset
отсутствует, выполнение arrow не будет нарушено. Такой
подход полезен для библиотек и компонентов с динамическим набором
модификаторов.
Даже если зависимость явно не указана, порядок модификаторов в массиве имеет значение:
const popperInstance = Popper.createPopper(reference, popper, {
modifiers: [
{ name: 'offset', options: { offset: [0, 8] } },
{ name: 'preventOverflow' },
{ name: 'flip' }
]
});
В этом примере:
offset смещает поппер.preventOverflow ограничивает положение поппера.flip при необходимости переворачивает поппер.Если изменить порядок, например, поместив flip перед
preventOverflow, возможны неправильные
перевороты, потому что flip не увидит ограничение
границ.
requires для обязательных
зависимостей, чтобы Popper.js сам корректировал порядок выполнения.requiresIfExists.const popper = Popper.createPopper(reference, popperElement, {
modifiers: [
{
name: 'offset',
options: { offset: [0, 10] },
phase: 'main'
},
{
name: 'preventOverflow',
options: { padding: 8 },
phase: 'main',
requires: ['offset']
},
{
name: 'flip',
options: { fallbackPlacements: ['top', 'right'] },
phase: 'main',
requires: ['preventOverflow']
},
{
name: 'arrow',
options: { element: arrowElement },
phase: 'main',
requiresIfExists: ['offset']
}
]
});
В такой конфигурации каждая зависимость соблюдается, и порядок выполнения гарантирует корректное позиционирование поппера и стрелки.