前言
一般信息填写类的需求页面,都会增设「预览」和「打印」功能。我们会通过编写 DOM 及样式来绘制出预览视图,而打印则是基于预览来生成 PDF 文件。
浏览器原生 API window.print()
可以用于打印当前窗口(window.document)视图内容。调用此方法会产生一个打印预览弹框,用户可以根据具体设置来得到打印结果。
接下来将从代码层面带领大家熟悉「打印」的使用。
一、打印样式
默认情况下,基于页面上的内容,会将元素,布局和样式都进行打印;
如果仅想在打印上设置特殊样式,可以通过以下方式:
1.使用打印样式表:
<link href="print.css" media="print" rel="stylesheet" />
2.使用媒介查询:
@media print {
p{
color: lavender;
background: #ccc;
}
h1{
color: lightblue;
background: #ccc;
}
}
3.使用内联 media 属性
<style media="print">
p{
color: lavender;
background: #ccc;
}
h1{
color: lightblue;
background: #ccc;
}
</style>
默认情况下,元素的背景色不会被打印,可通过设置属性来支持:
div{
// Chrome、Safari 等 webkit 浏览器内核
-webkit-print-color-adjust: exact;
// 火狐
print-color-adjust: exact;
color-adjust: exact;
}
二、打印指定区域内容
默认情况下,调用 window.print() 会对整个 document.body 进行打印,当需要打印指定容器内容时,可以通过以下几种方式:
1.对容器内全部内容进行打印
<body>
<div id="container">
<p>这是一个段落</p>
<h1>这是一个标题</h1>
</div>
<input type="button" value="打印此页面" onclick="printpage()" />
<script>
const printpage = () => {
let newstr = document.getElementById("container").innerHTML;
let oldstr = document.body.innerHTML;
document.body.innerHTML = newstr;
window.print();
document.body.innerHTML = oldstr;
}
</script>
</body>
2.对容器内的部分内容进行打印
当只需要打印容器内某一部分内容时,可以通过注释标识进行截取。
<body>
<div id="container">
<!--startprint-->
<p>这是一个段落</p>
<!--endprint-->
<h1>这是一个标题</h1>
</div>
<input type="button" value="打印此页面" onclick="printpage()" />
<script>
const printpage = () => {
let oldStr = window.document.body.innerHTML; // 获取body的内容
let start = "<!--startprint-->"; // 开始打印标识, 17个字符
let end = "<!--endprint-->"; // 结束打印标识
let newStr = oldStr.substr(oldStr.indexOf(start) + 17); // 截取开始打印标识之后的内容
newStr = newStr.substring(0, newStr.indexOf(end)); // 截取开始打印标识和结束打印标识之间的内容
window.document.body.innerHTML = newStr; // 把需要打印的指定内容赋给body
window.print(); // 调用浏览器的打印功能打印指定区域
window.document.body.innerHTML = oldStr; // body替换为原来的内容
}
</script>
</body>
3.监听打印事件
通过监听打印前后事件,对不需要进行打印的元素进行隐藏和放开隐藏。
<body>
<div id="container">
<p>这是一个段落</p>
<h1 id="title">这是一个标题</h1>
</div>
<input type="button" value="打印此页面" onclick="printpage()" />
<script>
const printpage = () => {
window.print();
}
window.onbeforeprint = function() {
// 将一些不需要被打印的元素隐藏
document.getElementById('title').style.display = 'none';
}
window.onafterprint = function() {
// 放开隐藏的元素
document.getElementById('title').style.display = 'block';
}
</script>
</body>
4. iframe实现打印
上面几种方式都在当前窗口进行打印,并且都需要更改 document.body 内容,这会出现视图切换,带来的体验不是太好。
下面我们借助 iframe 来实现打印,并且不影响当前视窗的内容展示。
<body>
<div id="container">
<p>这是一个段落</p>
<h1 id="title">这是一个标题</h1>
</div>
<input type="button" value="打印此页面" onclick="printpage()" />
<script>
const printpage = () => {
const printContent = document.querySelector('#container').innerHTML;
const iframe = document.createElement('iframe');
iframe.setAttribute('style', 'position: absolute; width: 0; height: 0;');
document.body.appendChild(iframe);
const iframeDoc = iframe.contentWindow.document;
// 设置打印展示方式 - 横向展示
iframeDoc.write('<style media="print">@page {size: landscape;}</style>');
// 向 iframe 中注入 printContent 样式
iframeDoc.write(`<link href="./print.css" media="print" rel="stylesheet" />`);
// 写入内容
iframeDoc.write('<div>' + printContent + '</div>');
setTimeout(function(){
iframe.contentWindow?.print();
document.body.removeChild(iframe);
}, 50);
}
</script>
</body>
值得注意的是,iframe 是一个新的 window 窗口,不会复用当前窗口的样式,需要为 iframe 注入打印内容所需的样式。
三、自定义分页
当需要自定义打印分页时机时,可通过如下方式将指定 DOM 设为分割点。
1.在指定元素前添加分页符
@media print {
h1 {
page-break-before: always;
}
}
2.在指定元素后添加分页符
@media print {
h1 {
page-break-after: always;
}
}
四、打印设置
设置打印布局
@media print {
@page {
/* 纵向展示(高度展示内容更多) */
/* size: portrait; */
/* 横向(宽度展示内容更大) */
size: landscape;
/* 打印的边距 上右下左 */
margin: 1cm 2cm 1cm 2cm;
}
}
标签:body,浏览器,打印,window,iframe,print,document From: https://blog.csdn.net/qq_24956515/article/details/143403478注意,一旦设置为 size: landscape,在打印时将不能切换展示模式,包括纸张类的设置。