跟源码手写自己打印预览组件

2,250 阅读1分钟

前言

前一段时间碰到预览打印功能,也是第一次碰到,查一下资料window.print()就可以实现,但是实践起来的时候发现并没有那么简单。那就先使用一下插件先解决一下吧。后来去看了一下插件(react-to-print)怎么实现的。后面有完整代码。

正文

还是先来看看最后的结果,原理也很简单,只是我们通常不会想那么多。

原理:将页面中的DOM,style,link全都复制到iframe中,然后再在iframe中调用print()

动画23.gif

代码详解

  1. 组件参数props
interface PrintProps {
  /** 是否显示*/
  isShow: boolean,
  /** 打印的元素*/
  children: React.ReactNode,
  /** 打印时的样式*/
  pageStyle?: string,
  /** 点击取消按钮*/
  handleCancel?: () => any
  /** 打印前触发的事*/
  onBeforePrint?: () => any,
  /** 打印后触发的事*/
  onAfterPrint?: () => void
}
  1. 判断是否有正在进行中的打印任务和执行onBeforePrint函数,对于onBeforePrint的返回值进行判断。

code.png

  1. 创建iframe,并去除上一次打印添加的iframe,克隆需要打印的Dom结点。获取打印节点中全部的link、img、video标签,这里是为了预加载资源。为什么要预加载资源下面解释。

code.png

  1. canvas、form、style进行复制,对img、video、link的资源进行预加载。

code.png

  1. 使用requestAnimationFrame判断资源是否加载完毕,因为资源的加载需要时间,要是没有加载完成资源就调用打印,那么打印是空白的或者样式不对。

code.png

完整代码

仓库地址

参考代码

  1. react-to-print插件 (github.com)

结语

感兴趣的可以去试试