Popper.js — это мощная библиотека для управления позиционированием
всплывающих элементов (popper’ов) относительно таргетов. Одним из
ключевых аспектов её работы является объект state, который
содержит текущее состояние вычислений позиции, размеры элементов, а
также применяемые модификаторы. Понимание структуры state и
методов его логирования позволяет глубже контролировать поведение
поппера и выявлять ошибки при разработке сложных интерфейсов.
stateОбъект state передается в функции модификаторов и
содержит следующие основные свойства:
elements – объект с ключами
reference, popper и опционально
arrow, указывающими на соответствующие DOM-элементы.
state.elements = {
reference: HTMLElement, // элемент, к которому привязан popper
popper: HTMLElement, // сам popper
arrow: HTMLElement | null
}options – объект с конфигурацией
текущего Popper’а, включая placement,
modifiers и прочие настройки.
state.options = {
placement: 'bottom',
strategy: 'absolute',
modifiers: [...]
}placement – строка, определяющая
текущее положение поппера относительно reference. Возможные значения:
'top', 'bottom', 'left',
'right', с вариантами -start и
-end.
modifiersData – объект, где каждая
запись соответствует модификатору и содержит промежуточные результаты
его работы. Например, modifiersData.offset хранит текущие
смещения x и y.
rects – объект с размерами и
координатами reference и popper:
state.rects = {
reference: DOMRect,
popper: DOMRect
}strategy – позиционирование поппера
(absolute или fixed).
reset – флаг, указывающий, нужно ли
сбросить вычисления и повторить их.
Для анализа поведения поппера используются следующие подходы:
console.logНаиболее простой способ — вывод state в консоль из
модификатора:
const logStateModifier = {
name: 'logState',
enabled: true,
phase: 'write', // можно использовать 'read', 'main' или 'afterWrite'
fn({ state }) {
console.log('Popper state:', state);
}
};
const popperInstance = Popper.createPopper(referenceEl, popperEl, {
modifiers: [logStateModifier]
});
Особенности:
state, включая все размеры и
промежуточные вычисления.console.dir(state, { depth: null }), чтобы развернуть
вложенные свойства.Иногда необходимо отследить только конкретные значения, например смещения или текущее размещение:
fn({ state }) {
const { x, y } = state.modifiersData.popperOffsets || { x: 0, y: 0 };
console.log(`Popper offsets: x=${x}, y=${y}`);
console.log(`Current placement: ${state.placement}`);
}
Это снижает шум в консоли и ускоряет поиск ошибок.
Поппер хранит информацию о позиционировании и размерах, что позволяет
дополнительно визуализировать state:
state.rects.popper – размеры и координаты самого
popper’а.state.rects.reference – размеры и координаты
reference.style для
элементов:Object.assign(popperEl.style, {
top: `${state.rects.popper.top}px`,
left: `${state.rects.popper.left}px`
});
Это помогает наглядно увидеть несоответствие вычисленных координат с реальным отображением.
Фазы модификаторов. Логирование имеет смысл в разных фазах:
read – доступно состояние DOM и размеры элементов.main – применяются вычисленные смещения.write – можно изменить DOM после вычислений.afterWrite – финальные координаты и результаты
модификаторов.Модификаторы и modifiersData. Все
модификаторы, которые изменяют позиционирование, записывают свои
результаты в modifiersData. Логирование позволяет
убедиться, что смещения и адаптивные изменения работают
корректно.
Изменение state вручную. В
большинстве случаев рекомендуется только читать state. Но
если нужно корректировать позиции, это делается через
модификатор:
state.modifiersData.offset = { x: 10, y: 20 };
state.reset = true;
const logReferenceSize = {
name: 'logReferenceSize',
phase: 'read',
fn({ state }) {
const { width, height } = state.rects.reference;
console.log(`Reference size: ${width}x${height}`);
}
};
const logOffsets = {
name: 'logOffsets',
phase: 'main',
fn({ state }) {
const offsets = state.modifiersData.offset || { x: 0, y: 0 };
console.log(`Offsets applied: x=${offsets.x}, y=${offsets.y}`);
}
};
const logPlacement = {
name: 'logPlacement',
phase: 'afterWrite',
fn({ state }) {
console.log(`Final placement: ${state.placement}`);
}
};
statestate предоставляет полный контроль над
позиционированием и внутренними вычислениями Popper.js.state.rects, modifiersData и
placement обеспечивает точную диагностику проблем с
позиционированием popper’ов.