Доступ к state и options

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


Объект state

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

  • elements – объект с двумя ключами:

    • reference – элемент, к которому привязан Popper.
    • popper – сам всплывающий элемент.
  • placement – текущая выбранная сторона позиционирования ('top', 'bottom', 'left', 'right') с возможными вариациями ('-start', '-end').

  • strategy – стратегия позиционирования: 'absolute' или 'fixed'.

  • modifiersData – объект, хранящий данные всех активных модификаторов. Каждый модификатор может сохранять промежуточные результаты, используемые другими модификаторами или для рендеринга.

  • rects – размеры и позиции элементов:

    • reference – bounding client rect опорного элемента.
    • popper – bounding client rect Popper-а.
  • scrollParents – массив родительских элементов с прокруткой для reference и popper. Используется для корректного расчёта позиции в контексте scrollable контейнеров.

  • isDestroyed – флаг, показывающий, уничтожен ли инстанс Popper.

Пример доступа к state в модификаторе

const logStateModifier = {
  name: 'logState',
  enabled: true,
  phase: 'write',
  fn({ state }) {
    console.log('Текущее состояние Popper:', state);
  },
};

В этом примере на фазе write происходит вывод всех данных state в консоль. Использование state в модификаторах позволяет реализовывать кастомные эффекты, реагировать на изменения позиции и динамически управлять стилями.


Объект options

options отвечает за конфигурацию Popper-инстанса. Он передаёт настройки, которые определяют, как Popper должен вычислять позицию, применять модификаторы и управлять поведением. Основные поля:

  • placement – начальное предпочтение расположения Popper ('top', 'bottom-start' и т.д.).

  • modifiers – массив модификаторов, которые изменяют расчёт позиции, добавляют эффекты и корректируют поведение:

[
  {
    name: 'offset',
    options: { offset: [0, 10] }
  },
  {
    name: 'preventOverflow',
    options: { padding: 8 }
  }
]
  • strategy'absolute' или 'fixed', задаёт базовую стратегию позиционирования.

  • onFirstUpdate – функция, вызываемая после первого расчёта позиции, с доступом к state. Позволяет выполнять инициализацию или логирование.

Доступ к options в модификаторе

Модификаторы могут читать и изменять options, но изменения не всегда отражаются на уже созданном Popper-е, поэтому чаще используется только чтение для условного поведения:

const customModifier = {
  name: 'custom',
  enabled: true,
  phase: 'beforeWrite',
  fn({ state, options }) {
    if (options.placement.startsWith('top')) {
      state.styles.popper.backgroundColor = 'lightblue';
    }
  }
};

Фазы модификаторов и доступ к state и options

Popper.js разделяет жизненный цикл расчёта позиции на несколько фаз:

  1. beforeRead – подготовительные действия перед чтением DOM.
  2. read – сбор информации о размерах и положении элементов.
  3. afterRead – постобработка данных.
  4. beforeMain – подготовка к вычислениям.
  5. main – основной расчёт позиции.
  6. afterMain – постобработка расчёта.
  7. beforeWrite – подготовка к записи стилей.
  8. write – применение стилей и атрибутов.
  9. afterWrite – финальные действия после записи.

На каждой фазе модификатор получает доступ к state и options. Понимание фаз позволяет использовать state для чтения промежуточных результатов или записи окончательных стилей, а options — для условного поведения.


Практические сценарии использования

  • Динамическая подстройка позиции: анализ state.rects для автоматического выбора наилучшего расположения Popper.
  • Кастомные анимации: чтение state.placement для изменения анимации в зависимости от стороны.
  • Интерактивные компоненты: доступ к elements.reference и elements.popper позволяет добавлять события и реагировать на изменение размеров.
  • Логирование и отладка: использование модификаторов с state для мониторинга поведения Popper в сложных интерфейсах.

Рекомендации по работе с state и options

  1. Не изменять state напрямую без необходимости. Лучше использовать модификаторы, чтобы сохранить совместимость с внутренними механизмами Popper.js.
  2. Использовать options для конфигурации модификаторов и стратегий. Это облегчает масштабирование и переиспользование Popper-инстансов.
  3. Следить за фазами модификаторов. Изменения стилей должны происходить на фазах beforeWrite или write, а вычисления — на фазах main и afterMain.
  4. Использовать modifiersData для хранения промежуточных вычислений. Это позволяет передавать данные между модификаторами без вмешательства в основные поля state.

Доступ к state и options является ключом к созданию гибких и динамических всплывающих интерфейсов. Корректное использование этих объектов открывает возможности точного управления позиционированием и поведения Popper-а в любых сложных UI-сценариях.