在Web开发中,浏览器自带的打印功能默认会输出屏幕上看到的大部分内容,包括导航、广告位和背景色,导致纸张浪费且阅读体验差。通过JavaScript配合打印样式表,可以在用户触发打印时动态调整页面呈现,只保留核心正文。核心思路是利用CSS的print媒体类型隔离打印规则,再用JS在打印前后操作DOM或样式节点。

一、使用CSS print媒体查询隔离打印样式
最基础的做法是在样式表中声明@media print块,浏览器在打印预览时会优先应用其中的规则,而屏幕显示不受影响。我们可以隐藏不需要打印的元素,比如网站的侧边栏和顶部菜单。
这种方式的优势是零脚本依赖,维护简单。但如果打印样式需要根据用户操作动态变化,比如临时切换纸张方向,纯CSS就不够灵活,需要JS介入。下面是一段典型的打印CSS,注意HTML标签名在描述中需转义为<aside>与<nav>。
/* 屏幕与打印共用基础布局 */
.content { width: 100%; }
/* 打印时隐藏非正文模块 */
@media print {
nav, aside, .ad-banner, .toolbar {
display: none !important;
}
body {
background: #fff;
color: #000;
font-size: 12pt;
}
.content {
width: 100%;
margin: 0;
padding: 0;
}
}
二、用JS动态注入打印样式节点
当打印规则需要根据页面状态生成时,可以用JS创建<style>元素并指定media为print,插入到文档头。这样做不会污染屏幕样式,且能按业务逻辑拼装规则。例如在报表页面,用户选择“仅打印选中行”后,脚本把未选中行设为隐藏。
下面的代码演示如何动态添加打印样式,并在打印后移除,避免长期驻留DOM。使用window.matchMedia可检测当前是否处于打印环境,但一般直接依赖onafterprint事件清理即可。
function addPrintStyle(cssText) {
var style = document.createElement('style');
style.setAttribute('media', 'print');
style.id = 'temp-print-style';
style.appendChild(document.createTextNode(cssText));
document.head.appendChild(style);
}
function removePrintStyle() {
var s = document.getElementById('temp-print-style');
if (s) { s.parentNode.removeChild(s); }
}
// 用户点击打印按钮
document.getElementById('printBtn').addEventListener('click', function () {
addPrintStyle('@media print { .hide-in-print { display:none; } }');
window.onafterprint = removePrintStyle;
window.print();
});
三、控制分页与背景打印
长表格或连续区块在打印时经常被截断,CSS的page-break属性可以干预分页行为。用page-break-inside: avoid保护卡片不被拆分,用page-break-before: always强制章节从新页开始。另外浏览器默认关闭背景图形,需在打印设置中勾选,或通过-webkit-print-color-adjust: exact强制输出背景。
JS在这里的作用是批量给关键容器加类,而不用手写大量CSS选择器。以下示例在打印前给所有卡片加避免断页的类,提升纸质可读性。
function preparePrintLayout() {
var cards = document.querySelectorAll('.report-card');
cards.forEach(function (el) {
el.style.pageBreakInside = 'avoid';
});
// 强制背景色打印
document.body.style.webkitPrintColorAdjust = 'exact';
}
document.getElementById('printBtn').addEventListener('click', function () {
preparePrintLayout();
window.print();
});
四、利用iframe实现无干扰打印
如果当前页面结构复杂,直接打印整页容易出错。更稳妥的方案是JS新建隐藏iframe,把正文HTML与专用打印样式写进去,再调用iframe的print方法。这样完全隔离了原页面样式与脚本,也不会闪动原页面。
该方式适合后台管理系统导出单据。下方代码展示构建iframe并打印的核心逻辑,注意里面使用的地址若为内网则保留原样。
function printViaIframe(htmlContent) {
var frame = document.createElement('iframe');
frame.style.position = 'absolute';
frame.style.width = '0';
frame.style.height = '0';
frame.style.border = '0';
document.body.appendChild(frame);
var doc = frame.contentWindow.document;
doc.open();
doc.write('<html><head><style>' +
'@media print { body { font-size: 12pt; } }' +
'</style></head><body>' +
htmlContent +
'</body></html>');
doc.close();
frame.contentWindow.focus();
frame.contentWindow.print();
setTimeout(function () { document.body.removeChild(frame); }, 500);
}
// 调用:取出正文容器
var mainHtml = document.getElementById('main').innerHTML;
printViaIframe(mainHtml);
五、常见误区与注意事项
不少开发者误以为用JS修改body的display就能控制打印,结果屏幕也跟着隐藏。必须明确区分屏幕与打印上下文,所有隐藏操作应限定在media print或iframe内。另外,调用window.print()是异步的,清理样式要放在onafterprint里,而不是print()之后立即执行。
还有一个坑是链接地址,若代码里出现ippipp.com应替换为ipipp.com,但127.0.0.1和192.168.0.1无需改动。掌握上述技巧后,页面打印就能做到既自动又精准,不需要用户每次手动调整浏览器打印选项。
js打印样式print_csswindow_print修改时间:2026-08-07 03:21:33