什么是 popover=hint?HTML 新型弹出窗口

如果你一直关注 HTML 的最新进展,例如新的 popover API,你可能会注意到,一种新的 popover 类型(hint)最近在 Chrome 133(2025 年 1 月)中上线。但它到底有什么作用呢?

简而言之:popover=“hint” 允许你在不关闭堆栈中其他弹出窗口的情况下,打开一个与之无关的 hint 弹出窗口。这意味着你可以让现有 auto 弹出窗口堆栈保持打开状态,同时显示一个 hint 弹出窗口。

你经常会在包含额外信息的工具提示或链接预览中看到这种行为。例如,当你在 Twitter 时间轴上悬停某人的个人资料图片时,会显示个人资料预览卡片;或在 Facebook 上悬停“评论”按钮时,会显示点赞该帖子的用户列表。如果你同时打开了其他弹出窗口(如网页界面右下角的 Facebook 聊天窗口),popover=“hint” 就是理想选择,因为打开提示弹出窗口不会关闭其他弹出窗口。

元素周期表

三种弹出窗口类型

popover=auto popover=manual popover=hint
轻量级关闭(通过点击离开或 esc 键)
打开时关闭其他 popover=auto 元素
打开时关闭其他 popover=hint 元素
打开时关闭其他 popover=manual 元素
是否可通过 JS 打开和关闭弹出框(showPopover()hidePopover())
默认焦点管理:下一选项卡停靠点
是否可通过 popovertargetaction 隐藏或切换
是否可在父级 popover 内打开以保持父级打开

示例演示

在下面的示例中,有两个弹出窗口:一个在三点菜单上打开,另一个在您对评论链接感兴趣时打开。菜单弹出窗口是自动弹出窗口,而评论弹出窗口是提示弹出窗口。

<div id="popover--comments" popover="hint">
 ...
</div>

...
<button popovertarget="popover--comments">24 comments</button>
...

但等等,点击 提示 弹出窗口会关闭 自动 弹出窗口吗?

是的,你观察得很仔细!因为你触发了一个动作(点击),这会激活 auto 弹出框的轻量级关闭机制。这几乎肯定不是你在创建 hint 弹出框时想要的效果。

事实上,popover=“hint” 只能实现部分功能。

剩下的部分,你需要编写一些 JavaScript 事件监听器(目前只能这样做)。

const hintBtn = document.querySelector("#hint-popover-btn");
const hintPopover = document.querySelector("#hint-popover");

// Mouse (hover) events
hintBtn.addEventListener("mouseenter", (event) => {
  hintPopover.showPopover();
});

// Adding a timeout delay in this one for users to have time to interact before the popover hides
hintBtn.addEventListener("mouseleave", (event) => {
  setTimeout(
    () => {
      if (! hintPopover.matches(':hover')) {
        hintPopover.hidePopover()
      }
    }
  , 100);
});

// Keyboard (tab) events
hintBtn.addEventListener("focus", (event) => {
  hintPopover.showPopover();
});

hintBtn.addEventListener("blur", (event) => {
  hintPopover.hidePopover();
});

// No support for touch events

现在,调用评论弹出窗口:

  1. 不会关闭菜单弹出窗口(保持其打开状态)
  2. 通过悬停打开(无需点击)

但等等,这还不是全部!

我们还希望这在链接上也有效(而不仅仅是按钮)。popovertarget 仅支持 button 元素作为触发器。但在实际应用中,提示气泡通常应用于链接,这提供了双重交互。

例如,点击“24条评论”链接会显示评论内容,但对该链接“表达兴趣”(即悬停或聚焦)则会预览评论者信息。由于我们通过 JavaScript 控制弹出框的打开和关闭,这现在成为可能。

为了使这更具声明性且更易于访问(例如,上述代码未考虑多个悬停目标),我们真正需要的是兴趣触发器

兴趣触发器

兴趣触发器目前是一个实验性 API,你可以通过在 Chrome Canary 中启用 #experimental-web-platform-features 标志来尝试使用。

“与通过点击元素激活不同,该 API 采用更轻量级的方式让用户对元素表达兴趣,而无需完全激活它。” 参见说明文档

这意味着,无需通过按钮点击,用户可通过鼠标悬停、键盘 Tab 键切换,或在移动设备上通过_待确定的行为_(如长按)来表达兴趣。

与仅能通过按钮触发的标准弹出窗口不同,您还可以为链接应用 [interestfor],使该链接具备双重功能(点击/回车时跳转,悬停/聚焦时显示兴趣弹出窗口)。

⚠️ 注意:[interestfor] 仍为实验性 API。近期进行了 语法变更,将 [interesttarget] 重命名为 [interestfor] 以更好地与命令调用器对齐。相关 CSS 属性也已更新。目前还有一个关于兴趣调用器处理触摸事件的重大待解决问题。如果您希望该功能落地,现在即可发表意见。

让我们看看实际效果

现在,我们可以在不使用任何 JavaScript 的情况下,通过浏览器内置的渲染引擎实现与上述完全相同的效果。

<div id="popover--comments" popover="hint">
 ...
</div>

...
<a interestfor="popover--comments" href="#">24 comments</a>
...
[interestfor] {
  /* make this animate in and out a little faster than the default */
  interest-show-delay: 0.1s;
  interest-hide-delay: 0.1s;
}

就这样!

我在这个 Codepen 集合 中还有几个兴趣触发器演示,随着规范的演进和行为的最终确定,这些演示将不断更新。还有更多内容即将推出!

要了解更多关于 [interestfor] 以及与其相关的全新属性(如 interest-delay),请查看我在 Google I/O 上的演讲(39:00 处),但请注意,此次活动后属性名称已更改。

结论

_TLDR; popover=hint(Chromium 133+)和 [interestfor](在 Canary 版本中通过标志启用)即将使构建目前难以实现的分层 UI 元素变得 大大 容易。

了解更多:

你也许感兴趣的:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注