window.print() 默认打印整页而非选中 div,因其未接收打印范围指令;需通过@media print隐藏非目标元素、print.js库指定目标或iframe注入HTML实现局部打印。

为什么直接用 window.print() 看不到打印预览效果
因为浏览器默认不激活 @media print 样式,除非真正触发打印流程(比如按 Ctrl+P),否则 CSS 中的打印规则不会生效。很多编辑器试图在页面上“模拟”打印样式,结果发现字体、边距、分页全不对——根本原因是没让浏览器进入打印媒体上下文。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用
matchMedia('print')主动切换媒体类型,再强制重绘:先window.matchMedia('print').matches = true(不行,只读),所以得换路子 - 正确做法是临时将整个编辑区域包裹进一个
<div id="print-preview">,然后用 <code>document.styleSheets动态注入或启用专为打印设计的<style></style>块 - 更稳妥的是创建 iframe,把当前 HTML + 打印 CSS 注入其中,再调用
iframe.contentWindow.print()—— 这样能真实触发打印媒体查询 - 不要复用主页面的
<link>,而是用iframe.contentDocument.write()写入完整 HTML 文档,包含独立的<style media="print"></style>块 - 确保打印样式中显式重置关键属性:
body { margin: 0; padding: 0; font-size: 12pt; },否则浏览器默认打印边距和缩放会干扰预览 - 避免使用
display: none隐藏非打印元素——某些打印机驱动会忽略它;改用@media print { .no-print { visibility: hidden; } }更可靠 - 只对块级元素(如
<p></p>、<section></section>)设break-inside: avoid,对<div> 默认无效,除非加 <code>display: block - 用
break-before: always强制分页比依赖avoid更可控,但要小心嵌套结构导致空白页 - 测试时别只看 iframe 预览,必须用真实打印对话框(Ctrl+P)确认——Chrome 的“另存为 PDF”模式比预览窗口更接近实际输出
- 用
MutationObserver监听编辑区域根节点变化,而不是靠事件代理 - 每次变更后,重新生成 iframe 内容(不要试图 patch),避免样式污染和状态残留
- 给 iframe 设置唯一
srcdoc属性而非空src,防止跨域限制或缓存旧内容
如何安全注入打印专用 CSS 到 iframe 预览区
直接写 <link rel="stylesheet" media="print"> 在主页面里,iframe 里不会继承;而且如果原页面用了 !important 或内联样式,打印样式容易被覆盖。
实操建议:
立即学习“前端免费学习笔记(深入)”;
分页控制失效?page-break-inside: avoid 不起作用的原因
现代浏览器对分页支持很有限,尤其当内容是 flex/grid 布局、或父容器有 overflow: hidden 时,page-break-inside 和 break-inside 基本被无视。
实操建议:
立即学习“前端免费学习笔记(深入)”;
编辑器实时更新后,打印预览没同步?
常见错误是只监听 input 事件,但用户粘贴、拖拽、快捷键(Ctrl+Z)等操作不会触发它;而且 iframe 一旦创建,其 DOM 就和主编辑器失去绑定。
实操建议:
立即学习“前端免费学习笔记(深入)”;
最麻烦的不是写代码,是不同浏览器对 @media print 的解析差异——Edge 会忽略 rem 单位的行高,Safari 对 break-after 支持滞后。真要稳定,就得在预览前做一次轻量 CSS normalize,比如把 1.5rem 换成 18px(假设基础字号 12px)。



















