标签搜索
侧边栏壁纸
  • 累计撰写 36 篇文章
  • 累计收到 59 条评论

popover API

shthah
2024-10-06 / 4 评论 / 71 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年12月11日,已超过135天没有更新,若内容或图片失效,请留言反馈。

2023 年 5 月至 6 月发布的Chrome 114和 Edge 114配备了名为“Popover API”的 API。

弹出框和模态框之间的区别

弹出窗口和模态框都是显示在屏幕顶部的 UI,但关键的区别在于它们是否允许在显示时操作其他元素。显示模式时,无法进行滚动或单击其他元素等操作。另一方面,这次介绍的弹出窗口是一个 UI,允许您在显示时操作其他元素。

没有 JavaScript 的弹出窗口

使用 popover API,您可以在不使用 JavaScript 的情况下创建如下所示的 popover。
popover.gif

只需指定HTML属性即可实现

实现这个弹出窗口非常简单。

  1. popover将属性赋予弹出框主体并为其指定任意 id(id="popover1"等等)。
  2. 向要控制 popover 打开和关闭的按钮添加属性popovertarget,并指定 1 中给出的 id。
<!-- 控制弹出按钮 -->
<button popovertarget="popover1">Popover 1</button>
<!-- 弹窗 -->
<div id="popover1" popover class="popover-content">
  <p>不使用JavaScript就可以实现最低限度的功能。</p>
</div>

<!-- 控制弹出按钮 -->
<button popovertarget="popover2">Popover 2</button>
<!-- 弹窗 -->
<div id="popover2" popover class="popover-content">
  <p>打开第二个弹出按钮后,第一个自动关闭</p>
</div>

这就是创建一个简单的弹出窗口所需的全部内容。除了易于实现之外,popover API 还标配有有用的功能。

弹出框 API 中包含的标准功能

(1)放置在顶层
使用此 API 的弹出框主体默认放置在顶层。该层比较特殊,z-index总是出现在屏幕的顶部,无论其他元素的值如何。
(2) 可以轻松取消
您可以通过“在弹出窗口外部单击”或“按某个键”来Esc关闭弹出窗口。 MDN 文档称此为“轻微驳回”。
(3) 如果有多个popover,其他的会自动关闭
通常,屏幕上只能显示一个弹出窗口。因此,如果有两个弹出窗口,并且您在第一个弹出窗口打开时打开第二个弹出窗口,则第一个弹出窗口将自动关闭。

添加弹出窗口样式

  • :popover-open:指向弹出窗口的打开状态的伪类。
  • ::backdrop:放置在弹出框后面作为背景的伪元素。
/*  :popover-open 开启时 */
.popover-content:popover-open {
  width: 300px;
  height: 120px;
  border-radius: 8px;
  border: none;
  padding: 24px;
  box-shadow: 8px 8px 10px #707070;
  background: #ffffff;
}
/* 背景 ::backdrop */
.popover-content::backdrop {
  background-color: #505050;
  opacity: 0.5;
}

Toast 实现

这是一个实现 Toast 的示例,该 Toast 通知用户进程已完成或使用 popover API 出现错误。
230530_toast.gif

手动显示/隐藏弹出窗口

在第一个例子中popover,popovertarget我们通过指定HTML属性来实现popover的显示/隐藏。
这次,我将使用JavaScript来手动切换显示/隐藏。

这里以下四点很重要。

  1. 指定创建为 toast 的div元素的popover属性。manual通过这样做,您可以创建一个不具有“轻松释放”和“屏幕上只有一个弹出窗口”功能的弹出窗口。
  2. 显示 toast 时showPopover()使用该方法。使用此方法显示时,它将被放置在顶层。
  3. hidePopover()使用一种方法来隐藏吐司。
  4. hidePopover()如果您这样做,该元素将保留在 DOM 中,因此remove()请使用该方法将其从 DOM 中删除。
const setupToast = ({ message, cssName }) => {
  // 创建dom 添加至 body
  const toast = createToastElm(message, cssName);
  document.body.appendChild(toast);
  // ⭐️showPopover 显示方法
  toast.showPopover();

  // -----省略-----
};

/**
 * 创建Toast
 * @param {string} message 文本内容
 * @param {string} cssName cssName
 * @return {HTMLDivElement} 返回dom
 */
const createToastElm = (message, cssName) => {
  const toast = document.createElement("div");
  // popover   "manual" 指定属性
  toast.popover = "manual";

  // -----省略-----

  // 关闭按钮
  const closeButton = document.createElement("button");
  closeButton.addEventListener("click", () => removeToast(toast));
  toast.appendChild(closeButton);
  return toast;
};

/**
 * 删除 toast
 * @param {HTMLDivElement} toast 删除dom
 */
const removeToast = (toast) => {
  toast.hidePopover();
  toast.remove();
};

切换事件检测

在此示例中,当创建或删除新 toast 时,toast 会重新排列并设置动画。处理顺序如下。

  1. 检测toast显示/隐藏
  2. 做动画

    • 显示时(创建新的 toast): 底部轻柔地显示一个新的 toast。
    • 隐藏时(toast 被删除):将整个内容向上移动

事件用于检测 toast 是显示还是隐藏toggle。
toggle该事件对于弹出框元素是唯一的,并且在显示或隐藏后立即触发。传递给此事件的event对象的值newState用于进一步分支动画。

// 显示和隐藏时重新排列
toast.addEventListener("toggle", (event) => {
  alignToast(event.newState === "closed");
});

// -----省略-----

const alignToast = (withMoveAnim) => {
  const toasts = document.querySelectorAll(".toast");
  // 把Toast按顺序竖着摆
  // withMoveAnim true:opacity translate 动画
  // withMoveAnim false:opacity 动画
  toasts.forEach((toast, index) => {
    toast.style.transition = withMoveAnim
      ? "translate 0.2s linear, opacity 0.2s linear"
      : "opacity 0.2s linear";
    toast.style.translate = `0px ${(56 + 10) * index}px`;
    toast.style.opacity = 1;
  });
};

event.newState 当值为 closed 时,会执行动画将屏幕上剩余的 toast 移至顶部,因为 toast 已消失;否则(event.newState值为open)时,执行动画以显示它们。

除了动画之外,我们还实现了一个在显示3秒后自动删除toast的实现

0

评论 (4)

取消
  1. 头像
    ensypvccyj
    Windows 10 · Google Chrome

    反讽手法运用娴熟,令人会心一笑。

    回复
  2. 头像
    bjgsphoite
    Windows 10 · Google Chrome

    情感浓度过高可适当留白,以达平衡。

    回复
  3. 头像
    fprdvbcfoz
    Windows 10 · Google Chrome

    作者的布局谋篇匠心独运,让读者在阅读中享受到了思维的乐趣。

    回复
  4. 头像
    dicccczeax
    Windows 10 · Google Chrome

    文章紧扣主题,观点鲜明,展现出深刻的思考维度。

    回复