前言
前一段时间碰到预览打印功能,也是第一次碰到,查一下资料window.print()
就可以实现,但是实践起来的时候发现并没有那么简单。那就先使用一下插件先解决一下吧。后来去看了一下插件(react-to-print
)怎么实现的。后面有完整代码。
正文
还是先来看看最后的结果,原理也很简单,只是我们通常不会想那么多。
原理:将页面中的DOM,style,link全都复制到iframe中,然后再在iframe中调用print()
代码详解
- 组件参数
props
interface PrintProps {
/** 是否显示*/
isShow: boolean,
/** 打印的元素*/
children: React.ReactNode,
/** 打印时的样式*/
pageStyle?: string,
/** 点击取消按钮*/
handleCancel?: () => any
/** 打印前触发的事*/
onBeforePrint?: () => any,
/** 打印后触发的事*/
onAfterPrint?: () => void
}
- 判断是否有正在进行中的打印任务和执行
onBeforePrint
函数,对于onBeforePrint
的返回值进行判断。
- 创建
iframe
,并去除上一次打印添加的iframe
,克隆需要打印的Dom
结点。获取打印节点中全部的link、img、video标签
,这里是为了预加载资源。为什么要预加载资源下面解释。
- 对
canvas、form、style
进行复制,对img、video、link
的资源进行预加载。
- 使用
requestAnimationFrame
判断资源是否加载完毕,因为资源的加载需要时间,要是没有加载完成资源就调用打印,那么打印是空白的或者样式不对。
完整代码
参考代码
结语
感兴趣的可以去试试