HTML Popover API真香,我用纯HTML写了个点赞气泡卡片

2026-08-16 0 405

上周刷浏览器更新日志,看到 Popover API 已经成为 Baseline 了。以前想做个气泡菜单,要么自己用 JS 定位再加全局点击监听,要么引入 Popper.js,现在浏览器直接给了原生的 popover 属性,用起来还挺顺手。本来没抱太大期望,结果用它做了一个“点赞气泡卡片”之后,我默默删掉了几十行监听事件。

这篇文章不是翻译文档,而是拿着一个实际例子带你把玩一下这个属性。全部代码只有 HTML,连 JS 都只用了半行(用于关闭按钮)。如果你还没试过,可以自己复制到一个 .html 文件里跑一下。

Popover 是什么不多说,直接看怎么用

最简单的用法是给一个元素加上 popover 属性,它默认隐藏。再给一个按钮加 popovertarget 属性指向那个元素的 id,点击按钮就能实现开关。

<button popovertarget="tip">点我</button>

<div id="tip" popover>
    我是默认气泡
</div>

就这么简单,点按钮弹出来,点气泡外部它就自动关闭。如果你的 popover 属性值是 "auto"(默认就是 auto),它还会同时只显示一个,点别的地方就关,像原生下拉菜单。

我想做个“点赞后显示操作气泡”

最近在弄一个文章卡片,希望用户点“点赞”图标的时候,浮出一个小气泡,里面有“情绪”选项,比如“开心”、“赞”、“666”。以前我得用 setTimeout、动态创建 DOM、再绑个 document 点击事件。现在有了 popover,感觉清爽了。

先看一下我最终的结构。

<article id="post-card">
    <h3>今天也是元气满满的一天</h3>
    <p>早起做了30个俯卧撑,然后喝了一大杯冰美式…</p>
    <footer>
        <button id="like-btn" popovertarget="like-pop" style="font-size: 18px;">👍 点赞</button>
        <div id="like-pop" popover>
            <div class="pop-actions">
                <button data-emoji="😄">开心</button>
                <button data-emoji="👍">纯赞</button>
                <button data-emoji="🔥">上头</button>
            </div>
        </div>
    </footer>
</article>

注意这个按钮上没有写 JS,浏览器会帮我切换 popover 的显示状态。但问题来了:我希望点击气泡里面的某个情绪按钮后,把点赞按钮上的表情换成对应的 emoji,并且把 popover 关掉。

让气泡里的按钮替“点赞”按钮换表情

这个需求就需要一点点 JS。不过也是简单到没朋友。因为 popover 元素在 DOM 里正常存在,我直接监听它的点击事件就行。

<script>
    const likeBtn = document.getElementById('like-btn');
    const likePop = document.getElementById('like-pop');

    likePop.addEventListener('click', (e) => {
        const emoji = e.target.dataset.emoji;
        if (emoji) {
            likeBtn.textContent = emoji + ' ' + e.target.textContent.trim();
            likePop.hidePopover(); // 原生方法关闭
        }
    });
</script>

这里用到的 hidePopover() 是 popover 元素自带的 JS 方法,比手动取消一个 class 舒服多了。当然你也可以写成 likePop.setAttribute('popover', ''),但都不够原生。

更进一步:让气泡的位置靠近按钮

默认弹出的 popover 是出现在页面视口的正中央,就跟 alert 一样。但实际产品里,气泡应该贴在点赞按钮附近。这个当前用纯属性还做不到,需要配合 CSS 的锚定定位(Anchor API)。

目前 Chrome 已经支持了锚定定位,但为了不跑偏,我先用个笨办法:把 popover 放进按钮的父容器,然后通过 CSS 去偏移。虽然不和“锚定定位”那么高级,但效果还行。

但咱们这文章说好不用样式,那就不展示。只说一下:你可以在 style 里给 #like-pop 设置 position: absolute; inset: unset; margin-top: 8px; 之类。等下,popover 元素默认是放在顶层(top-layer),它不在正常的文档流里,所以 absolute 定位相对于视口。还是用锚定定位靠谱。

说到锚定定位,其实 Popover API 的官方示例就是配合 anchor 属性使用的,但这又是一块内容。我这里不想把文章搞太长。不过还是可以给你看一个关键属性的雏形:

<div id="like-btn" anchor="like-pop">...</div>
<div id="like-pop" popover anchor="like-btn">...</div>

现在很多浏览器还没完全统一,真要在生产环境用,还是老老实实配个 transform 吧。

额外惊喜:popover 自动支持滚动关闭和取消关闭

做完了之后,我注意到一个细节:当 popover 弹出时,按 Esc 它会自动关闭。而且当你点击 popover 外部区域,它也会自动关闭。这在用户习惯上非常友好,完全不需要我再额外监听。

但有时候我们不想让它点击外部关闭,那就把 popover 的值设为 manual。手动模式会让它只能通过调用 showPopover()hidePopover() 来控制,适合做那种“必须明确选择”的确认框。

完整的“点赞气泡”HTML文件

下面这个文件你可以直接保存为 .html 运行,体验一下完整的效果。我没写任何样式,所以可能有点朴实无华,但交互都是好的。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Demo:点赞气泡</title>
</head>
<body>
    <article style="max-width: 400px; margin: 50px auto; border: 1px solid #ddd; padding: 16px;">
        <h2>周末去爬山</h2>
        <p>早上六点出门,爬山三小时,回来睡了一下午,感觉这才叫生活。</p>
        <hr>
        <button id="like-btn" popovertarget="like-pop">👍 点赞</button>

        <div id="like-pop" popover>
            <div style="display: flex; gap: 8px;">
                <button data-emoji="😄">开心</button>
                <button data-emoji="👍">纯赞</button>
                <button data-emoji="🔥">上头</button>
            </div>
        </div>
    </article>

    <script>
        const likeBtn = document.getElementById('like-btn');
        const likePop = document.getElementById('like-pop');

        likePop.addEventListener('click', (e) => {
            const emoji = e.target.dataset.emoji;
            if (emoji) {
                likeBtn.innerText = emoji + ' ' + e.target.innerText.trim();
                likePop.hidePopover();
            }
        });

        // 顺便展示一下手动控制的玩法:长按按钮强制显示气泡
        likeBtn.addEventListener('contextmenu', (e) => {
            e.preventDefault();
            likePop.showPopover();
        });
    </script>
</body>
</html>

我在这里给按钮加了个右键菜单事件,长按右键也会弹气泡,这是利用 showPopover() 方法。你如果不想要,删掉那段 JS 就行。

有些坑还是得记录

用下来发现几个问题:

  1. popover 会默认带上浏览器自带的边框和背景。 如果你没加任何 CSS,它可能长得很像老式弹窗。不过这正是定制的好起点,至少比之前用 div 模拟的强。
  2. 多个 popover="auto" 之间会互相顶掉。 这其实是特性,但如果你不小心把对话框也设成 auto,打开一个就会关掉另一个,有点尴尬。
  3. popover 里放 <form> 提交会把气泡关掉吗? 我试了一下,提交后不会自动关闭,需要手动关闭。这个要看场景。
  4. 移动端点击外部关闭有点难触发。 因为移动端没有 hover,但点击空白区域会自动关闭,感觉还行。

收尾

Popover API 的出现让很多常见交互变得“傻瓜化”。虽然现在很多人还在用框架做气泡,但原生能力迟早会被更多开发者用起来。如果你也遇到类似“点击某个元素弹出小卡片”的需求,不妨先别急着引第三方库,试试这个原生属性。也许会有惊喜。

HTML Popover API真香,我用纯HTML写了个点赞气泡卡片
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

版权声明:
本站资源有的来自互联网收集整理,本站纯免费分享提供学习使用,如果侵犯了您的合法权益,请联系本站我们会及时删除。
本站资源仅供研究、学习交流之用,免费开源项目不代表完全可商用,若商业用途请先咨询开发企业能否商用,否则产生的一切后果将由下载用户自行承担。
原创板块未经允许不得转载,否则将追究法律责任。

淘吗网 html HTML Popover API真香,我用纯HTML写了个点赞气泡卡片 https://www.taomawang.com/web/html/2554.html

下一篇:

已经没有下一篇了!

常见问题

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务