Popper.js 修饰符(modifiers)
Popper 使用可扩展的核心构建,它提供了用于交付库提供的所有功能的基础。
该库提供的所有有用功能都作为 Popper 修饰符实现。 它们是插件或中间件,可以钩入到 Popper 的生命周期中,并为 Popper 默认提供的定位操作添加额外的逻辑。 它们以某种方式有效地“修改”popper 状态,添加功能,因此称为“修饰符”。
自定义修饰符
我们可以通过在 Popper 实例化期间在options.modifiers
数组中定义它们来添加由您自定义的修饰符。
示例修饰符
当它在顶部时记录到控制台的修饰符(不是很有用,但演示了每个属性)
const topLogger = {
name: 'topLogger',
enabled: true,
phase: 'main',
fn({ state }) {
if (state.placement === 'top') {
console.log('Popper is on the top');
}
},
};
createPopper(reference, popper, {
modifiers: [topLogger],
});
有以下属性的修饰符
type Modifier = {|
// Required properties
name: string,
enabled: boolean,
phase: ModifierPhases,
fn: (ModifierArguments<Options>) => ?State,
// Optional properties
requires?: Array<string>,
requiresIfExists?: Array<string>,
effect?: (ModifierArguments<Options>) => ?() => void,
options?: {},
data?: {},
|};
type ModifierArguments<Options: Obj> = {
state: $Shape<State>,
instance: Instance,
options: $Shape<Options>,
name: string,
};
name
这个 name
用作标识符,以便可以从库的其他部分引用修饰符。 例如,您可以使用name
属性将对象添加到 options.modifier 数组,并且 options 属性填充了一些自定义选项,以覆盖内置修饰符的选项。
createPopper(reference, popper, {
modifiers: [
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'bottom'],
},
},
],
});
enabled
如果将enabled设置为 true,则修饰符将在 Popper 生命周期内执行,否则将被忽略。
phase
Popper 的修饰符生命周期分为 3 个核心阶段:read
、main
和 write
。 这样做是为了优化库,以便它对 DOM 的访问被组合在一起,而不是分散在整个生命周期中。
需要从 DOM 读取的修饰符应该运行在读取阶段,只执行算法逻辑的修饰符应该在 主要阶段,而写入 DOM 的应该在写入阶段。
请注意,Popper 在其状态中提供了 DOM 测量值的缓存,以修饰符可以读取它们而不是查询 DOM,从而优化整体执行时间。这意味着您应该很少需要进入读取阶段。
如果需要,为了进一步细化,还有 2 个其他子阶段:之前和之后。 以下是完整列表:
- beforeRead(读前)
- read(读)
- afterRead(读后)
- beforeMain
- main
- afterMain
- beforeWrite(写之前)
- write(写)
- afterWrite(写后)
fn
这是主用于为修饰符提供逻辑的函数。
在某些情况下,您可能希望通过修饰符控制 Popper 生命周期——例如,翻转修饰符可以改变放置选项,如果发生这种情况,Popper 会被指示再次运行所有修饰符,以便它们可以对更新后的修饰符做出反应 放置值。 修饰符可以通过将state.reset
设置为 true 来重置生命周期。
requires
requires
指定它所依赖的修饰符列表。 Popper 会以正确的顺序执行修饰符,允许依赖修饰符访问被依赖修饰符提供的数据。
例如, offset 依赖于 popperOffsets 数据,因为它会改变其属性。
简而言之,修饰符取决于修饰符数据列表才能工作。
requiresIfExists
指定它所依赖的修饰符列表,但前提是这些修饰符确实存在。
比如preventOverflow
依赖offset
,但前提是offset
确实存在,因为offset
改变了popperOffsets
数据,preventOverflow
需要读取和变异。 如果offset
不存在,preventOverflow
仍将正常工作。
简而言之,修饰符依赖于这个修饰符的行为列表(或来自其他修饰符的依赖数据的突变)来工作。
effect
该函数允许您在运行第一个更新周期之前执行任意代码(效果)。 在函数中执行效果并在必要时返回清理函数:
function effect() {
// perform side effects
return () => {
// cleanup side effects
};
}
这有用的示例涉及不需要在每次更新时运行的代码,而仅在实例生命周期更改(创建、更新或销毁)时运行:
eventListeners
修饰符使用它来添加和删除不属于主修饰符更新周期的窗口/文档事件侦听器。- 箭头修饰符使用它来将元素添加到
state.elements
。 箭头修饰符依赖于preventOverflow (run after)
,但 preventOverflow 依赖于state.elements.arrow
。 由于效果在第一个更新周期之前运行,因此问题已解决。
options
这是一个具有用于配置修饰符的所有属性的对象。
data
这是提供给 state.modifiersData.<MODIFIER_NAME>
的初始数据,共享给其他要读取或操作的修饰符
常用的Popper.js修饰符
Modifiers | 描述 |
---|---|
popperOffsets | popperOffsets 修饰符是 Popper 的核心,它计算将 popper 元素定位到参考元素附近所需的偏移量。 换句话说,如果没有这个修饰符,你根本没有理由使用 Popper |
offset | offset 修饰符让你从它的引用元素中置换一个 popper 元素 |
preventOverflow | preventtoverflow修饰符通过移动popper来防止popper被切断,使其在其边界区域内保持可见。 |
arrow | 箭头修饰符定位弹出窗口的内部元素,使其看起来相对于引用元素居中,通常是指向引用元素的三角形或插入符号。 |
flip | 当popper溢出给定边界时,flip修饰符可以改变它的位置。 |
hide | 隐藏修饰符可以让你隐藏popper,如果它看起来与它的引用元素分离,或者没有附加到任何东西。当引用元素在滚动容器中,而popper在不同的上下文中时,可能会发生这种情况。 |
computeStyles | computeStyles修饰符准备将在下一阶段写入DOM的样式,即写入。这包括对偏移进行舍入并决定要使用的属性(例如gpuAcceleration)。 |
applyStyles | applyStyles修饰符在状态中写入样式。风格和状态。属性设置为 popper 元素。如果你正在使用 React 这样的库,你可能想要实现你自己的 applyStyles 修饰符 fn 来委托DOM写入它。 |
eventListeners | eventListeners修饰符添加了滚动和调整大小的侦听器 |