notification api 仅在 https 或 localhost 下生效,http 页面(含局域网地址)会静默失败,permission 始终为 "default" 或 "denied",new notification() 无反应。

Notification API 在 HTTP 页面里根本不会弹出来
直接双击打开本地 index.html,或者用 Nginx/Apache 跑在 http://192.168.x.x 这类非 localhost 的 HTTP 地址,Notification.requestPermission() 会静默失败,控制台无报错,Notification.permission 始终卡在 "default" 或 "denied",new Notification() 调用后完全没反应。
这不是代码写错了,是浏览器强制策略:只有安全上下文(https:// 或 http://localhost)才允许触发桌面通知。
- 开发阶段老实用
live-server、http-server或 VS Code 的 Live Server 插件,确保地址是http://localhost:5500/这种 - 上线前必须配 HTTPS,HTTP + 自签名证书也无效
- Safari 对
localhost的 Notification 支持从 15.4 版本才开始,旧版 Safari 用户只能降级用alert()或标题闪烁
dialog.showModal() 报 “Failed to execute 'showModal'” 怎么办
这个错误几乎只出现在异步回调里:比如 fetch().then(() => dialog.showModal())、setTimeout(() => dialog.showModal(), 100),或事件委托中触发。浏览器判定这不是“用户激活行为”,直接拒绝模态展示。
它和权限无关,也不是 DOM 没挂载好,纯粹是触发时机不合法。
- 最稳妥做法:把
dialog.showModal()放在原生点击事件的同步路径里,例如button.addEventListener('click', () => dialog.showModal()) - 如果必须等接口返回后再决定是否弹窗,可用
setTimeout(() => dialog.showModal(), 0)推到下一个宏任务——仅绕过校验,不是长期方案 - 千万别用
dialog.style.display = "block"代替,它不锁背景、不支持 ESC 关闭、不进模态栈,和真正showModal()行为完全不同
右上角小红点(badge)显示逻辑容易漏掉的三件事
小红点看着简单,但实际常因状态不同步、DOM 更新不及时或样式覆盖出问题。
- 初始隐藏必须用
display: none,不能只靠opacity: 0或visibility: hidden,否则仍占可访问性焦点 - 更新未读数时,先设
badge.textContent = count,再根据count > 0切换.show类;别只改 class 忘了填数字,也别只填数字不控制显隐 - 如果消息来自 WebSocket 或轮询,注意防抖:避免连续收到 5 条消息就触发 5 次 DOM 更新,用
requestIdleCallback或简单节流包装更新函数
<output></output> 是 HTML5 专为操作反馈设计的语义化标签,比如“保存成功”“正在上传”。但它本身不会主动通知屏幕阅读器——必须配合 aria-live。
- 普通提示(如“已提交”)用
aria-live="polite" role="status",等用户暂停操作再读 - 紧急错误(如“网络断开”)用
aria-live="assertive" role="alert",立刻打断当前播报 - 动态更新时别直接
innerHTML = "新文本",先清空再赋值:el.textContent = ""→el.textContent = "上传完成",避免残留节点和读屏混乱 - IE 全系不识别
<output></output>,但降级成本极低——它默认渲染为普通内联元素,视觉无差别,重点是别指望它在旧 IE 里有语义作用
全局消息提示最难的不是“怎么让它出现”,而是“怎么让它该出现时不卡顿、该消失时不残留、该读出来时不被跳过”。很多问题藏在安全上下文、触发时机、可访问性属性这些看似边缘的地方,一漏就全盘失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











