现代浏览器已基本弃用beforeprint/afterprint事件,应改用window.matchmedia('print')检测打印状态,并结合@media print样式与window.print()主动控制流程。

beforeprint 和 afterprint 事件在现代浏览器中基本不可靠
Chrome、Edge(基于Chromium)从2021年起已完全移除 beforeprint 和 afterprint 事件支持;Firefox 自92版起也标记为“deprecated”,实际触发行为不稳定;Safari 从未实现。这意味着依赖这两个事件做打印状态检测的代码,在绝大多数真实用户环境中会静默失效。
常见错误现象包括:addEventListener('beforeprint', ...) 注册后完全不触发、仅在旧版IE或极少数Electron旧版本中偶然生效、控制台无报错但逻辑断链。
- 不要把业务关键逻辑(如打印前清空表单、打印后重置UI)绑定在这两个事件上
- 若项目仍需兼容IE11,可保留作为降级路径,但必须搭配主动检测 fallback
- Electron 应用需查清 Chromium 版本:v85+ 已移除,不能依赖内置事件
用 window.matchMedia('print') 检测当前是否处于打印预览
window.matchMedia('print') 是目前唯一被所有主流浏览器稳定支持的打印状态检测方式。它返回一个 MediaQueryList 对象,其 matches 属性实时反映当前是否处于打印媒体查询上下文(即用户点了「打印」或进入打印预览)。
注意:它只表示「当前样式环境是 print」,不区分是预览还是实际出纸,也不表示打印已完成。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 监听方式:
const mql = window.matchMedia('print'); mql.addEventListener('change', e => { if (e.matches) { /* 进入打印 */ } else { /* 退出打印 */ } }); - 首次获取状态应直接读
mql.matches,而非等 change 事件 - 该 API 在 iframe 中同样有效,但需确保同源
- 性能无负担,无需节流,change 事件本身是同步且轻量的
打印完成无法精确捕获,只能按场景做妥协处理
浏览器没有提供「打印任务真正结束」(纸张吐出/队列清空)的回调。所谓「打印完成」在前端语义里只有两种近似替代:
- 用户关闭打印预览窗口 → 触发
window.matchMedia('print').matches === false,这是最可靠的「退出打印」信号 - 用户点击了浏览器打印对话框的「打印」按钮 → 此时页面通常会短暂冻结,但无事件通知;可结合
setTimeout延迟执行「假设已提交」逻辑(如隐藏打印专用按钮),但存在误判风险 - 服务端打印(如通过后端生成PDF)则完全绕过前端打印流程,此时应由业务接口返回结果,而非监听前端事件
典型陷阱:试图用 onafterprint 全局属性或 window.onafterprint 回调捕获完成,这在 Chrome/Firefox 中早已无效,且不会抛错,容易让人误以为逻辑正常。
实际打印控制建议用 CSS @media print + JS 主动触发
比起被动监听不可靠的事件,更可控的做法是:用 @media print 控制样式,用 window.print() 主动发起,并在调用前后手动管理状态。
- 打印前:添加临时 class(如
is-printing),配合 CSS 隐藏非必要元素、调整字体大小等 - 打印中:
window.print()调用后,页面会进入打印样式上下文,window.matchMedia('print').matches立即变为 true - 打印后:监听
matchMedia的change事件,当e.matches === false时,移除 class、恢复 UI、清理临时数据 - 避免在
window.print()后立刻操作 DOM —— 浏览器可能尚未切换媒体状态,建议加微小延迟或依赖 change 事件驱动
复杂点在于:用户可能不通过 window.print() 触发打印(比如右键菜单、快捷键 Ctrl+P),这时只能依赖 matchMedia 的自动响应,无法区分主动/被动入口。这点容易被忽略,但决定了你能否统一处理所有打印来源。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










