在开发中,我们常遇到这样的痛点:一个下拉菜单不仅要处理展开收起,还得兼顾焦点管理和无障碍访问(Accessibility),更别提那无穷无尽的 z-index 层级大战了。移动端上按 ESC 键退出的逻辑经常罢工,至于'点击空白处自动关闭'的代码,往往是一团难以维护的屎山。
好消息是,Popover API 已经实现了广泛的浏览器支持。这意味着现在可以在 Chrome、Firefox、Safari 和 Edge 里直接使用它。我最近将旧有的组件彻底重构,只用了区区几行纯 HTML 代码就搞定了一切——一行 JS 都没写!
这就是 HTML Popover API,一种纯原生、声明式的解决方案,能让你在不碰 JS 的情况下,轻松实现各种浮层、提示框(Tooltip)、菜单和对话框。
过去为了搞个浮层,前端开发者需要手动维护定位、监听外部点击、手撸焦点捕获,还要挂载各种 ARIA 属性。而现在,浏览器把这些脏活累活全包了。今天我们就来聊聊如何仅凭 HTML 属性,就能实现以前必须依赖 Tippy.js 或 Floating UI 才能搞定的复杂交互。
跟 JS 组件库说拜拜:纯享版 Popover
传统的浮层实现方式通常是这样:你得用绝对定位把元素钉死,小心翼翼地防着 z-index 冲突,老老实实地写监听器来捕捉外部点击,手撸焦点捕获,加上 ESC 键监听,最后还要用 JS 把这一大坨逻辑串联起来。
// 传统方式:手动处理状态与事件监听
const button = document.querySelector('.trigger');
const popover = document.querySelector('.popover');
let isOpen = false;
button.addEventListener('click', () => {
isOpen = !isOpen;
popover.style.display = isOpen ? 'block' : 'none';
popover.style.zIndex = '9999';
if (isOpen) {
popover.setAttribute('aria-hidden', 'false');
// 还要手写焦点捕获...
// 还要加点击外部关闭监听...
// 还要加 ESC 键监听...
}
});
// 点击外部关闭的逻辑
document.addEventListener('click', () => {
(!popover.(e.) && !button.(e.)) {
isOpen = ;
popover.. = ;
}
});

