React如何实现浏览器打印部分内容详析


Posted in Javascript onMay 19, 2019

前言

近期着手项目任务的打印功能,在此作个记录,本文介绍基于React的一种调用浏览器打印页面指定内容的方法。

整体思路: 通过构建一个隐藏的元素(该元素包裹需打印的内容),当打印行为触发时,将页面其他的一些不需要打印的元素隐藏,然后将需打印的元素追加到body中,打印完成后,再恢复初始状态即可。浏览器打印的本质还是将web页面中的元素打印出来而已。

1. 构建待打印元素

在页面中构建一个display为none的元素,里面的内容为你需要打印的内容。我们还需要设置包裹打印内容的元素的ref属性,以便于后面获取到元素。

<div style={{ display: 'none' }}>
 <div ref={el => (this.printRef = el)}>
 { 打印内容 }
 </div>
</div>

2. 打印动作触发时的处理

处理流程:

  1. 获取待打印元素;
  2. 将根元素隐藏;
  3. 将待打印元素追加到body中;
  4. 调用浏览器的打印预览;
  5. 预览界面关闭后,将待打印元素从body中移除,将原始页面恢复。
let printView = this.state.printRef //获取待打印元素
document.querySelector('#root').className = 'print-hide' //将根元素隐藏
document.body.appendChild(printView) //将待打印元素追加到body中
window.print() //调用浏览器的打印预览
document.body.removeChild(printView) //将待打印元素从body中移除
document.querySelector('#root').className = '' //将原始页面恢复

对应的CSS设置:

@page {
 size: A4;
 margin: 0;
}
@media print {
 html, body {
  min-width: 0;
  width: 210mm; 
  height: 297mm;
 }
 .print-hide {
 visibility: hidden!important;
 display: none!important;
 }
}

其中,@page中的size可以自己设置纸张的大小,如果是A4纸可以直接设置值为A4,媒体查询@media print中设置的是打印时的样式,因为打印设备知道其输出区域的物理大小,所以使用厘米(cm)、毫米(mm)、英寸(in)等作为打印设计的单位完全可行。

补充(其他原生的打印方法)

直接替换body的内容为要打印的内容,之后再重新刷新页面。

const old = window.document.body.innerHTML //备份原来的页面
window.document.body.innerHTML = ''
window.document.body.appendChild(/* 将你要打印的内容附加到这 */)
window.print() //调用print()函数时,会跳出打印预览的界面,以下的代码被阻塞,关闭预览界面后继续执行
window.document.body.innerHTML = old
window.location.reload() //重新加载旧页面

打开一个新窗口,将打印内容放到新窗口打印,打印结束后关闭新窗口

const newWindow = window.open("打印窗口", "_blank")
const docStr = '<div>test</div>' //需要打印的内容
newWindow.document.write(docStr)
const styles = document.createElement("style")
styles.setAttribute('type', 'text/css') //media="print"
styles.innerHTML = ''
newWindow.document.getElementsByTagName('head')[0].appendChild(styles)
newWindow.print()
newWindow.close()

以上两种方法可能会造成CSS样式应用无效的问题。

3. 注意点

第二小节的步骤2中的意思是:将页面中所有不需要打印的元素隐藏,特别注意像模态窗Model这些元素,也要为它们加上 'print-hide'className属性。

如果需要在特定位置强制分页打印,可以尝试在对应元素上设置page-break-before:always !importantpage-break-after:always !importantCSS属性,该属性只对块级元素有效。

进入打印预览后,我们无法获知用户最终是选择了打印,还是选择了取消。这里若有人知道解决方法的话,欢迎留言。

React如何实现浏览器打印部分内容详析

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery 1.0.2
Oct 11 Javascript
javascript实现的网页局布刷新效果
Dec 01 Javascript
JavaScript Cookie 直接浏览网站分网址
Dec 08 Javascript
2012年开发人员的16款新鲜的jquery插件体验分享
Dec 28 Javascript
用innerhtml提高页面打开速度的方法
Aug 02 Javascript
Javascript动画效果(2)
Oct 11 Javascript
fetch 使用及如何接收JS传值
Nov 11 Javascript
js自定义trim函数实现删除两端空格功能
Feb 09 Javascript
其实你可以少写点if else与switch(推荐)
Jan 10 Javascript
Vue 实现从文件中获取文本信息的方法详解
Oct 16 Javascript
vue组件库的在线主题编辑器的实现思路
Apr 03 Javascript
如何在 Vue 表单中处理图片
Jan 26 Vue.js
koa-router路由参数和前端路由的结合详解
May 19 #Javascript
Vue.js中该如何自己维护路由跳转记录
May 19 #Javascript
利用Vue实现一个markdown编辑器实例代码
May 19 #Javascript
小程序实现搜索界面 小程序实现推荐搜索列表效果
May 18 #Javascript
微信小程序实现搜索指定景点周边美食、酒店
May 18 #Javascript
vue+高德地图写地图选址组件的方法
May 18 #Javascript
微信小程序实现搜索功能并跳转搜索结果页面
May 18 #Javascript
You might like
PHP中的正则表达式函数介绍
2012/02/27 PHP
解析关于java,php以及html的所有文件编码与乱码的处理方法汇总
2013/06/24 PHP
Linux+Nginx+MySQL下配置论坛程序Discuz的基本教程
2015/12/23 PHP
基于PHP实现发微博动态代码实例
2020/12/11 PHP
js实现权限树的更新权限时的全选全消功能
2009/02/17 Javascript
js 对象是否存在判断
2009/07/15 Javascript
jQuery中on()方法用法实例
2015/01/19 Javascript
js光标定位文本框回车表单提交问题的解决方法
2015/05/11 Javascript
jQuery插件datepicker 日期连续选择
2015/06/12 Javascript
简介JavaScript中用于处理正切的Math.tan()方法
2015/06/15 Javascript
JavaScript中两个字符串的匹配
2016/06/08 Javascript
JS采用绝对定位实现回到顶部效果完整实例
2016/06/20 Javascript
详解jQuery中关于Ajax的几个常用的函数
2017/07/17 jQuery
webpack配置sass模块的加载的方法
2017/07/30 Javascript
vue 粒子特效的示例代码
2017/09/19 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
Vue实现搜索 和新闻列表功能简单范例
2018/03/16 Javascript
Vue2.0 实现单选互斥的方法
2018/04/13 Javascript
vue使用Google地图的实现示例代码
2018/12/19 Javascript
Nodejs对postgresql基本操作的封装方法
2019/02/20 NodeJs
p5.js绘制旋转的正方形
2019/10/23 Javascript
vue:el-input输入时限制输入的类型操作
2020/08/05 Javascript
python使用正则表达式匹配字符串开头并打印示例
2017/01/11 Python
Python初学时购物车程序练习实例(推荐)
2017/08/08 Python
使用Python的Django和layim实现即时通讯的方法
2018/05/25 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
介绍一款python类型检查工具pyright(推荐)
2019/07/03 Python
Matplotlib.pyplot 三维绘图的实现示例
2020/07/28 Python
python中altair可视化库实例用法
2021/01/26 Python
洛杉矶健身中心女性专用运动服饰品牌:Marika
2018/05/09 全球购物
Booking.com亚太地区:Booking.com APAC
2020/02/07 全球购物
2014年党务公开方案
2014/05/08 职场文书
大一新生军训新闻稿
2015/07/17 职场文书
详解PHP用mb_string处理windows中文字符
2021/05/26 PHP
python基础之函数的定义和调用
2021/10/24 Python
警用民用对讲机找不同
2022/02/18 无线电