HTML Invoker Commands来了:以后写弹窗不用再碰JavaScript
做前端开发的人都知道,写一个弹窗、一个下拉菜单、一个弹出层,都得这么来:
const button = document.querySelector('#open-btn');
const dialog = document.querySelector('#my-dialog');
button.addEventListener('click', () => {
dialog.showModal();
});就为了让按钮点一下把弹窗打开,得写三行JavaScript。这还不算关弹窗的代码。
现在不用了。浏览器新出了一个叫Invoker Commands的东西,直接给html按钮加了两个属性,让按钮自己能控制别的元素。点一下按钮打开弹窗、关弹窗、切换菜单,一行JavaScript都不用写。
这东西已经在Chrome 135、Firefox 144、Safari 26.2里正式上线了。也就是说,现在你打开浏览器就能用。
核心就两个属性
Invoker Commands给<button>加了两个新属性:
commandfor:告诉按钮你要控制谁,填那个元素的ID
command:告诉按钮你要干啥,比如打开、关闭、切换
就这么简单。
来看个最直观的例子。以前打开一个对话框要写JS,现在这样就行:
<button commandfor="my-dialog" command="show-modal">
打开对话框
</button>
<dialog id="my-dialog">
<p>这个对话框没用一行JS代码就弹出来了</p>
<button commandfor="my-dialog" command="close">
关闭
</button>
</dialog>点"打开对话框",弹窗出来。点"关闭",弹窗消失。没有JavaScript,没有事件监听,没有dom查询。
目前支持哪些命令
浏览器内置的命令现在有这些:
| 类型 | 命令 | 作用 |
|---|---|---|
| Popover(弹出层) | toggle-popover | 切换显示/隐藏 |
| show-popover | 显示 | |
| hide-popover | 隐藏 | |
| Dialog(对话框) | show-modal | 以模态框形式打开 |
| close | 关闭 | |
| request-close | 请求关闭(会触发cancel事件) |
做个弹出菜单试试
以前写这种设置菜单,得写JS控制显示隐藏。现在这样就行:
<button commandfor="settings-menu" command="toggle-popover">设置</button>
<div id="settings-menu" popover>
<h3>设置菜单</h3>
<label><input type="checkbox"> 深色模式</label>
<label><input type="checkbox"> 消息通知</label>
<label><input type="checkbox"> 自动保存</label>
<button commandfor="settings-menu" command="hide-popover">完成</button>
</div>点设置按钮,菜单弹出来。点完成,菜单关上。又是零JS。
如果你需要更复杂的功能:自定义命令
内置命令够用大部分场景。但如果你想要自己的命令,比如点按钮让图片翻转,也可以。
自定义命令的规矩:前面加两个破折号--。
<button commandfor="photo" command="--flip-horizontal">
水平翻转
</button>
<button commandfor="photo" command="--rotate-90">
旋转90度
</button>
<img id="photo" src="vacation.jpg" alt="照片">这时候需要写几行JS来接收命令:
document.getElementById('photo').addEventListener('command', (e) => {
if (e.command === '--flip-horizontal') {
e.target.style.transform = 'scaleX(-1)';
} else if (e.command === '--rotate-90') {
e.target.style.transform = 'rotate(90deg)';
}
});注意:command事件是发在被控制的元素上(这里是img),不是按钮上。事件对象里有个e.command,就是你定义的那个命令名。
跟以前的写法有啥不一样
以前控制popover,是用popovertarget和popovertargetaction这两个属性。现在Invoker Commands提供了一个更统一的方式——不管控制dialog还是popover,都用同一套commandfor和command。
而且这两个属性可以跟老的那套共存,你想慢慢迁移也行。
浏览器支持情况
2026年1月,Invoker Commands已经在所有主流浏览器里实现基础支持。
Chrome:135版本开始支持(2025年4月发布)
Firefox:144版本开始支持(2025年10月发布)
Safari:26.2版本开始支持(2025年12月发布)
也就是说,现在已经可以在项目里用了。
这东西有啥好处
第一,少写很多重复代码。以前每个按钮都要写事件监听,现在直接写在HTML里。对于dialog、popover这种高频组件,能省不少事。
第二,交互不用等JS加载。以前页面刚打开的时候,如果JS还没加载完,点按钮可能没反应。现在HTML自己就能处理交互,首屏体验更好。
第三,无障碍(accessibility)天生就好。屏幕阅读器、键盘导航都支持得不错,不用自己手动加一堆ARIA属性。
第四,Web Components用着更方便。组件作者可以给组件定义一套命令,别人用的时候直接写command="--my-action"就行,不用关心内部怎么实现的。
以后还会支持啥
现在内置命令还不多,主要是popover和dialog。但官方已经在讨论加更多命令了:
媒体控制(播放、暂停)
details元素的展开折叠
全屏切换
复制、分享
表单控件控制
Open UI的文档里还提到,以后可能支持<details>的open、close、toggle命令。GitHub上也有讨论说要不要加add-class、toggle-class这种命令。
写在最后
Invoker Commands不是什么能改变世界的大东西,但它把前端开发里最烦人的一件小事给解决了——让按钮控制其他元素,这事本来就应该HTML自己干。
有开发者说得好:"每次Web平台出了新特性,让我们能把实现逻辑往技术栈上游移,我就很兴奋。Invoker Commands就是把按钮点击处理逻辑移到了HTML层"。
以后写代码的时候,遇到按钮控制弹窗这种活,先想想能不能直接用HTML解决。JS应该去处理那些真正复杂的事,基础交互交给浏览器就够了。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!