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 个核心阶段:readmainwrite 。 这样做是为了优化库,以便它对 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修饰符添加了滚动和调整大小的侦听器

查看笔记

扫码一下
查看教程更方便