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 相关文章推荐
向大师们学习Javascript(视频与PPT)
Dec 27 Javascript
javascript 利用Image对象实现的埋点(某处的点击数)统计
Dec 28 Javascript
js与jquery获取父级元素,子级元素,兄弟元素的实现方法
Jan 09 Javascript
javascript bom是什么及bom和dom的区别
Nov 26 Javascript
json实现添加、遍历与删除属性的方法
Jun 17 Javascript
微信小程序 自定义对话框实例详解
Jan 20 Javascript
node.js中express-session配置项详解
May 31 Javascript
详解Vue基于 Nuxt.js 实现服务端渲染(SSR)
Apr 05 Javascript
Layui数据表格之获取表格中所有的数据方法
Aug 20 Javascript
vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定
Sep 14 Javascript
解决vue A对象赋值给B对象,修改B属性会影响到A的问题
Sep 25 Javascript
CKeditor富文本编辑器使用技巧之添加自定义插件的方法
Jun 14 Javascript
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
linux下使用crontab实现定时PHP计划任务失败的原因分析
2014/07/05 PHP
解读PHP中上传文件的处理问题
2016/05/29 PHP
PHP 配置后台登录以及模板引入
2017/01/24 PHP
浅谈Laravel中的一个后期静态绑定
2017/08/11 PHP
javascript的trim,ltrim,rtrim自定义函数
2008/09/21 Javascript
Jquery异步请求数据实例代码
2011/12/28 Javascript
基于jquery的鼠标拖动效果代码
2012/05/30 Javascript
ExtJS判断IE浏览器类型的方法
2014/02/10 Javascript
jQuery EasyUI中DataGird动态生成列的方法
2016/04/05 Javascript
JS实时弹出新消息提示框并有提示音响起的实现代码
2016/04/20 Javascript
vue.js从安装到搭建过程详解
2017/03/17 Javascript
Centos6.8下Node.js安装教程
2017/05/12 Javascript
基于vue.js快速搭建图书管理平台
2017/10/29 Javascript
微信小程序云开发修改云数据库中的数据方法
2019/05/18 Javascript
vue通过video.js解决m3u8视频播放格式的方法
2019/07/30 Javascript
简单的Apache+FastCGI+Django配置指南
2015/07/22 Python
Linux CentOS7下安装python3 的方法
2018/01/21 Python
Python无损音乐搜索引擎实现代码
2018/02/02 Python
理论讲解python多进程并发编程
2018/02/09 Python
python清除字符串中间空格的实例讲解
2018/05/11 Python
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
python简单鼠标自动点击某区域的实例
2019/06/25 Python
Python selenium实现断言3种方法解析
2020/09/08 Python
Python Sqlalchemy如何实现select for update
2020/10/12 Python
如何设置Java的运行环境
2013/04/05 面试题
如何选择使用结构还是类
2014/05/30 面试题
十一个高级MySql面试题
2014/10/06 面试题
秘书专业自荐信范文
2013/12/26 职场文书
大学生职业规划范文:象牙塔生活的四年计划
2014/01/14 职场文书
小学科学教学反思
2014/01/26 职场文书
小学开学典礼主持词
2014/03/19 职场文书
2014年最新大专生职业生涯规划书范文
2014/09/13 职场文书
评估“风险”创业计划的几大要点
2019/08/12 职场文书
基于Redis6.2.6版本部署Redis Cluster集群的问题
2022/04/01 Redis
德劲DE1102数字调谐收音机机评
2022/04/07 无线电
MySQL提取JSON字段数据实现查询
2022/04/22 MySQL