使用JavaScript打印页面指定div内容时CSS样式不生效如何解决?
问题根因
- JS代码中将CSS的
<link>标签写在了<body>区域而非<head>区域,浏览器不会优先加载解析body内的样式文件 - 引用CSS时使用了本地磁盘绝对路径
C:\Users\Intel\Envs\test\project\static\doc.css,浏览器出于安全策略禁止网页直接加载本地磁盘文件 - 未给CSS链接添加
media="print"或media="all"属性,打印时浏览器会默认忽略未指定打印媒体属性的样式 - 固定500ms延迟触发打印,可能CSS还未加载完成就执行了打印操作,导致样式不生效
可行解决方案
方案一:修正原有iframe打印逻辑
调整标签结构、CSS路径和打印触发时机,修改后代码如下:
$(function () { $("#btnPrint").click(function () { var contents = $("#content").html(); var frame1 = $('<iframe />'); frame1[0].name = "frame1"; frame1.css({ "position": "absolute", "top": "-1000000px" }); $("body").append(frame1); var frameDoc = frame1[0].contentWindow ? frame1[0].contentWindow : frame1[0].contentDocument.document ? frame1[0].contentDocument.document : frame1[0].contentDocument; frameDoc.document.open(); frameDoc.document.write('<html><head><title>DIV Contents</title>'); // CSS放到head标签内,路径和HTML中使用的静态路径保持一致,添加media属性 frameDoc.document.write('<link href="{% static 'doc.css' %}" rel="stylesheet" type="text/css" media="all" />'); frameDoc.document.write('</head><body>'); frameDoc.document.write(contents); frameDoc.document.write('</body></html>'); frameDoc.document.close(); // 监听iframe加载完成后再触发打印,替换固定延迟逻辑 frame1.on('load', function () { window.frames["frame1"].focus(); window.frames["frame1"].print(); frame1.remove(); }); }); });
方案二:更稳定的媒体查询打印方案(无需iframe)
不需要动态创建iframe,直接通过CSS媒体查询隐藏非打印区域,代码兼容性更强:
- 在
doc.css末尾添加如下样式:
@media print { /* 隐藏所有不需要打印的元素 */ body * { visibility: hidden; } /* 仅保留目标打印区域可见 */ #content, #content * { visibility: visible; } /* 将打印内容定位到页面左上角,避免留白 */ #content { position: absolute; left: 0; top: 0; } /* 可选:强制浏览器打印背景色/背景图 */ * { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }
- 简化打印触发JS:
$(function () { $("#btnPrint").click(function () { window.print(); }); });
注意事项
- 如果打印时需要显示背景色、背景图,需要在打印预览的设置中手动开启「背景图形」选项
- 打印内容的CSS尽量使用px、pt等固定单位,避免使用vw、vh等相对视口单位,防止打印排版错乱
内容的提问来源于stack exchange,提问作者Ritankar Bhattacharjee
相关产品推荐
相关产品推荐

