Popper.js 使用方法

在本教程中,您将通过构建一个基本的工具提示来学习如何使用 Popper。

请记住,Popper 不是工具提示库,而是构建工具提示库的基础! 按照下面的教程学习如何使用 Popper。


配置

创建一个包含两个元素的新HTML文档,一个<button>和一个工具提示<div>,并将它们传递给Popper:

<!DOCTYPE html>
<html>
  <head>
    <title>Popper Tutorial</title>
  </head>
  <body>
    <button id="button" aria-describedby="tooltip">My button</button>
    <div id="tooltip" role="tooltip">My tooltip</div>

    <script src="https://unpkg.com/@popperjs/core@2"></script>
    <script>
      const button = document.querySelector('#button');
      const tooltip = document.querySelector('#tooltip');

      const popperInstance = Popper.createPopper(button, tooltip);
    </script>
  </body>
</html>

样式

让我们为工具提示提供一些样式:

    <style>
      #tooltip {
        background: #333;
        color: white;
        font-weight: bold;
        padding: 4px 8px;
        font-size: 13px;
        border-radius: 4px;
      }
    </style>

运行结果:

popper示例结果

尝试一下


使用箭头

我们的工具提示目前只是一个方框。在许多UI设计系统中,这是所有工具提示所需的,但其他人更喜欢使用指向引用元素的箭头。

添加一个带有 data-popper-arrow属性的元素,如下所示:

<div id="tooltip" role="tooltip">
  My tooltip
  <div id="arrow" data-popper-arrow></div>
</div>

样式如下:

#arrow,
#arrow::before {
  position: absolute;
  width: 8px;
  height: 8px;
  background: inherit;
}

#arrow {
  visibility: hidden;
}

#arrow::before {
  visibility: visible;
  content: '';
  transform: rotate(45deg);
}

需要使用 ::before 伪元素,因为Popper使用transform将箭头定位在Popper内部,但我们希望使用自己的transform将箭头框旋转成菱形。

现在我们需要根据Popper的当前位置偏移箭头。Popper属性为Popper数据提供以下信息

#tooltip[data-popper-placement^='top'] > #arrow {
  bottom: -4px;
}

#tooltip[data-popper-placement^='bottom'] > #arrow {
  top: -4px;
}

#tooltip[data-popper-placement^='left'] > #arrow {
  right: -4px;
}

#tooltip[data-popper-placement^='right'] > #arrow {
  left: -4px;
}

"^="表示开始的位置

运行结果:

poppe带箭头r示例结果

尝试一下


Offset

我们的箭头当前与参考重叠,我们可以使用Offset为其提供8px的距离:

const popperInstance = Popper.createPopper(button, tooltip, {
  modifiers: [
    {
      name: 'offset',
      options: {
        offset: [0, 8],
      },
    },
  ],
});

结果如下:

poppe带箭头并设置offset示例结果

尝试一下


功能

我们只希望在悬停或聚焦按钮时显示工具提示。

#tooltip {
  /* ... */
  display: none;
}

#tooltip[data-show] {
  display: block;
}
function show() {
  tooltip.setAttribute('data-show', '');

  // We need to tell Popper to update the tooltip position
  // after we show the tooltip, otherwise it will be incorrect
  popperInstance.update();
}

function hide() {
  tooltip.removeAttribute('data-show');
}

const showEvents = ['mouseenter', 'focus'];
const hideEvents = ['mouseleave', 'blur'];

showEvents.forEach((event) => {
  button.addEventListener(event, show);
});

hideEvents.forEach((event) => {
  button.addEventListener(event, hide);
});

运行结果:

poppe带箭头示例动态结果


性能

一旦我们使用 createPopper 创建了一个 popper,它就会保持“活跃”状态。 这意味着在滚动页面时,popper 会不断更新,即使它不可见。 我们可以在工具提示隐藏时禁用事件监听器来优化它:

function show() {
  // 使工具提示可见
  tooltip.setAttribute('data-show', '');

  // 启用事件侦听器
  popperInstance.setOptions((options) => ({
    ...options,
    modifiers: [
      ...options.modifiers,
      { name: 'eventListeners', enabled: true },
    ],
  }));

  //更新位置
  popperInstance.update();
}

function hide() {
  // 隐藏工具提示
  tooltip.removeAttribute('data-show');

  // 禁用事件侦听器
  popperInstance.setOptions((options) => ({
    ...options,
    modifiers: [
      ...options.modifiers,
      { name: 'eventListeners', enabled: false },
    ],
  }));
}

完整代码

<!DOCTYPE html>
<html>
  <head>
    <title>Popper Tutorial</title>
    <style>
      #tooltip {
        background: #333;
        color: white;
        font-weight: bold;
        padding: 4px 8px;
        font-size: 13px;
        border-radius: 4px;
        display: none;
      }

      #tooltip[data-show] {
        display: block;
      }

      #arrow,
      #arrow::before {
        position: absolute;
        width: 8px;
        height: 8px;
        background: inherit;
      }

      #arrow {
        visibility: hidden;
      }

      #arrow::before {
        visibility: visible;
        content: '';
        transform: rotate(45deg);
      }

      #tooltip[data-popper-placement^='top'] > #arrow {
        bottom: -4px;
      }

      #tooltip[data-popper-placement^='bottom'] > #arrow {
        top: -4px;
      }

      #tooltip[data-popper-placement^='left'] > #arrow {
        right: -4px;
      }

      #tooltip[data-popper-placement^='right'] > #arrow {
        left: -4px;
      }
    </style>
  </head>
  <body>
    <button id="button" aria-describedby="tooltip">My button</button>
    <div id="tooltip" role="tooltip">
      My tooltip
      <div id="arrow" data-popper-arrow></div>
    </div>

    <script src="https://unpkg.com/@popperjs/core@2"></script>
    <script>
      const button = document.querySelector('#button');
      const tooltip = document.querySelector('#tooltip');

      const popperInstance = Popper.createPopper(button, tooltip, {
        modifiers: [
          {
            name: 'offset',
            options: {
              offset: [0, 8],
            },
          },
        ],
      });

      function show() {
        // 使工具提示可见
        tooltip.setAttribute('data-show', '');

        // 启用事件侦听器
        popperInstance.setOptions((options) => ({
          ...options,
          modifiers: [
            ...options.modifiers,
            { name: 'eventListeners', enabled: true },
          ],
        }));

        // 更新位置
        popperInstance.update();
      }

      function hide() {
        // 隐藏工具提示
        tooltip.removeAttribute('data-show');

        // 禁用事件侦听器
        popperInstance.setOptions((options) => ({
          ...options,
          modifiers: [
            ...options.modifiers,
            { name: 'eventListeners', enabled: false },
          ],
        }));
      }

      const showEvents = ['mouseenter', 'focus'];
      const hideEvents = ['mouseleave', 'blur'];

      showEvents.forEach((event) => {
        button.addEventListener(event, show);
      });

      hideEvents.forEach((event) => {
        button.addEventListener(event, hide);
      });
    </script>
  </body>
</html>

尝试一下


您现在已经使用 Popper 创建了一个基本的工具提示! 当然,您还可以做更多的事情,例如添加动画或交互性。 在为工具提示、弹出框、下拉菜单等常见 popper 元素创建抽象时,这些由您来探索。

查看笔记

扫码一下
查看教程更方便