dialog 默认不显示,必须用 showmodal() 或 show() 激活;showmodal() 为模态式(带遮罩、禁背景交互、esc 关闭),show() 为非模态式;close() 关闭并触发 close 事件,返回值通过 dialog.returnvalue 获取,且该事件不冒泡。

dialog 元素默认不显示,必须用 showModal() 或 show() 激活
很多人写完 <dialog></dialog> 发现页面上根本看不到——这不是 bug,是标准行为。<dialog></dialog> 默认 display: none,连 visibility: hidden 都不是,它压根不在渲染流里。直接设 style="display: block" 无效,CSS 强制显示会破坏模态逻辑(比如失焦拦截、背景遮罩、Esc 关闭等)。
必须调用原生方法:
-
myDialog.showModal():模态式弹出(带 backdrop、禁用背景交互、按 Esc 自动关闭) -
myDialog.show():非模态式(无 backdrop,背景可操作,需手动管理焦点) -
myDialog.close():关闭 dialog(触发close事件),close()接收一个可选字符串参数作为返回值,比如dialog.close('confirm')
点击 backdrop 或按 Esc 关闭时,close 事件不会冒泡,且 event.target 是 dialog 本身
常见错误是给 dialog 内部按钮加 click 监听后,顺手在父容器上监听 close 事件却没生效——因为 close 是 dialog 的专属事件,不冒泡,也不能委托。
正确写法:
const dialog = document.getElementById('my-dialog');
dialog.addEventListener('close', () => {
console.log('dialog closed, returnValue:', dialog.returnValue); // 取到 close() 传入的值
});
// ✅ 不要这样写:
// document.body.addEventListener('close', ...) // 不会触发
另外注意:showModal() 下点击 backdrop 触发 close,但 show() 下点击 backdrop **不会**触发 —— 这是浏览器原生行为,无法更改。
dialog 在 Safari 中支持度有限,iOS 16.4+ 才完整支持 showModal()
Safari 一直拖到 iOS 16.4 / macOS Ventura 13.3 才支持 showModal() 和 backdrop 样式。旧版本 Safari 调用 showModal() 会抛错:TypeError: dialog.showModal is not a function。
稳妥做法是运行时检测 + 降级:
- 检查
dialog.showModal是否为函数 - 不支持时,用
show()+ 手动添加半透明<div class="backdrop"> 并管理 focus/escape <li>避免依赖 <code>::backdrop伪元素做样式(Safari 旧版不支持)
简单检测示例:
if (typeof dialog.showModal === 'function') {
dialog.showModal();
} else {
dialog.show();
// 插入自定义 backdrop 并绑定 escape 监听
}
dialog 内部表单提交后默认会关闭,除非显式 event.preventDefault()
这是最容易被忽略的隐式行为:<dialog></dialog> 内的 <form></form> 提交(无论 button type="submit" 还是回车)会自动触发 dialog.close(),且不经过任何 JS 控制。
如果你需要提交后保持 dialog 开着(比如校验失败要留着提示),必须拦截 form 的 submit 事件:
const form = dialog.querySelector('form');
form.addEventListener('submit', (e) => {
e.preventDefault(); // ❗关键:否则 dialog 会立刻关闭
// 执行你的提交逻辑(fetch、校验等)
});
同理,如果用了 button[type="submit"] 却没包 form,它不会触发关闭;但一旦包在 form 里,就受此规则约束——这个行为没有开关,只能靠 preventDefault 拦。











