Popper.js v2 представляет собой полностью переработанную архитектуру позиционирования элементов. Основные изменения затрагивают систему модификаторов, производительность, API и способы подключения. Версия v1 больше не развивается, что делает переход необходимым для получения исправлений ошибок, улучшенной точности позиционирования и поддержки современных браузеров.
Ключевые улучшения:
В v1 использовался пакет popper.js, в v2 —
@popperjs/core.
npm uninstall popper.js
npm install @popperjs/core
Импорт в коде:
import { createPopper } from '@popperjs/core';
В v1:
import Popper from 'popper.js';
new Popper(reference, popper, {
placement: 'top',
});
createPopper(reference, popper, {
placement: 'top',
});
Основное отличие:
createPopper вместо
конструктораnewmodifiers: {
offset: {
offset: '0,10'
}
}
modifiers: [
{
name: 'offset',
options: {
offset: [0, 10],
},
},
]
Изменения:
name и
optionsВ v1:
offset: '0, 10'
В v2:
offset: [0, 10]
Также поддерживаются функции:
offset: ({ placement, reference, popper }) => {
return [0, 10];
}
В v1:
modifiers: {
flip: {
beh * avior: ['top', 'bottom']
}
}
В v2:
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'bottom'],
},
}
Изменения:
behavior заменён на
fallbackPlacementsВ v1:
modifiers: {
preventOverflow: {
boundariesElement: 'viewport'
}
}
В v2:
{
name: 'preventOverflow',
options: {
boundary: 'viewport',
},
}
Переименования:
boundariesElement → boundaryВ v1:
modifiers: {
arrow: {
element: arrowElement
}
}
В v2:
{
name: 'arrow',
options: {
element: arrowElement,
},
}
Изменения минимальны, но структура модификаторов унифицирована.
В v1 использовалось свойство positionFixed:
positionFixed: true
В v2:
strategy: 'fixed'
Возможные значения:
'absolute' (по умолчанию)'fixed'В v1:
popper.scheduleUpdate();
В v2:
instance.update();
Или асинхронно:
await instance.update();
В v1:
popper.destroy();
В v2:
instance.destroy();
Метод сохранился, но возвращаемый объект отличается.
В v1 использовалось:
data.offsets.popper
В v2:
state.rects.popper
Или:
state.modifiersData
Структура данных изменилась и стала более детализированной.
modifiers: {
myModifier: {
enabled: true,
fn: function(data) {
return data;
}
}
}
{
name: 'myModifier',
enabled: true,
phase: 'main',
fn({ state, options }) {
return state;
},
}
Новые концепции:
phase)stateВ v2 введена система фаз:
beforeReadreadafterReadbeforeMainmainafterMainbeforeWritewriteafterWriteЭто позволяет:
| v1 | v2 |
|---|---|
| positionFixed | strategy |
| boundariesElement | boundary |
| behavior (flip) | fallbackPlacements |
| gpuAcceleration | computeStyles.options |
В v1:
gpuAcceleration: false
В v2:
{
name: 'computeStyles',
options: {
gpuAcceleration: false,
},
}
Теперь это отдельный модификатор.
В v1 стили применялись автоматически через
applyStyle.
В v2 используется модификатор:
{
name: 'applyStyles',
}
Можно отключить и управлять стилями вручную.
В v2 добавлена поддержка виртуальных элементов:
const virtualElement = {
getBoundingClientRect: () => ({
width: 0,
height: 0,
top: 100,
left: 100,
right: 100,
bottom: 100,
}),
};
createPopper(virtualElement, popper);
Это позволяет:
В v2:
1. Использование старого синтаксиса модификаторов
v1-объект не работает в v2 — требуется массив.
2. Неправильные имена опций
Например:
boundariesElement больше не существуетbehavior заменён3. Попытка использовать new Popper
В v2 только createPopper.
4. Игнорирование фаз модификаторов
Неправильная фаза может ломать логику позиционирования.
new Popper(reference, popper, {
placement: 'bottom',
modifiers: {
offset: {
offset: '0, 8',
},
preventOverflow: {
boundariesElement: 'viewport',
},
},
});
createPopper(reference, popper, {
placement: 'bottom',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8],
},
},
{
name: 'preventOverflow',
options: {
boundary: 'viewport',
},
},
],
});