React如何實(shí)現(xiàn)瀏覽器打印部分內(nèi)容詳析
前言
近期著手項(xiàng)目任務(wù)的打印功能,在此作個(gè)記錄,本文介紹基于React的一種調(diào)用瀏覽器打印頁(yè)面指定內(nèi)容的方法。
整體思路: 通過(guò)構(gòu)建一個(gè)隱藏的元素(該元素包裹需打印的內(nèi)容),當(dāng)打印行為觸發(fā)時(shí),將頁(yè)面其他的一些不需要打印的元素隱藏,然后將需打印的元素追加到body中,打印完成后,再恢復(fù)初始狀態(tài)即可。瀏覽器打印的本質(zhì)還是將web頁(yè)面中的元素打印出來(lái)而已。
1. 構(gòu)建待打印元素
在頁(yè)面中構(gòu)建一個(gè)display為none的元素,里面的內(nèi)容為你需要打印的內(nèi)容。我們還需要設(shè)置包裹打印內(nèi)容的元素的ref屬性,以便于后面獲取到元素。
<div style={{ display: 'none' }}>
<div ref={el => (this.printRef = el)}>
{ 打印內(nèi)容 }
</div>
</div>
2. 打印動(dòng)作觸發(fā)時(shí)的處理
處理流程:
- 獲取待打印元素;
- 將根元素隱藏;
- 將待打印元素追加到body中;
- 調(diào)用瀏覽器的打印預(yù)覽;
- 預(yù)覽界面關(guān)閉后,將待打印元素從body中移除,將原始頁(yè)面恢復(fù)。
let printView = this.state.printRef //獲取待打印元素
document.querySelector('#root').className = 'print-hide' //將根元素隱藏
document.body.appendChild(printView) //將待打印元素追加到body中
window.print() //調(diào)用瀏覽器的打印預(yù)覽
document.body.removeChild(printView) //將待打印元素從body中移除
document.querySelector('#root').className = '' //將原始頁(yè)面恢復(fù)
對(duì)應(yīng)的CSS設(shè)置:
@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可以自己設(shè)置紙張的大小,如果是A4紙可以直接設(shè)置值為A4,媒體查詢(xún)@media print中設(shè)置的是打印時(shí)的樣式,因?yàn)榇蛴≡O(shè)備知道其輸出區(qū)域的物理大小,所以使用厘米(cm)、毫米(mm)、英寸(in)等作為打印設(shè)計(jì)的單位完全可行。
補(bǔ)充(其他原生的打印方法)
直接替換body的內(nèi)容為要打印的內(nèi)容,之后再重新刷新頁(yè)面。
const old = window.document.body.innerHTML //備份原來(lái)的頁(yè)面 window.document.body.innerHTML = '' window.document.body.appendChild(/* 將你要打印的內(nèi)容附加到這 */) window.print() //調(diào)用print()函數(shù)時(shí),會(huì)跳出打印預(yù)覽的界面,以下的代碼被阻塞,關(guān)閉預(yù)覽界面后繼續(xù)執(zhí)行 window.document.body.innerHTML = old window.location.reload() //重新加載舊頁(yè)面
打開(kāi)一個(gè)新窗口,將打印內(nèi)容放到新窗口打印,打印結(jié)束后關(guān)閉新窗口
const newWindow = window.open("打印窗口", "_blank")
const docStr = '<div>test</div>' //需要打印的內(nèi)容
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()
以上兩種方法可能會(huì)造成CSS樣式應(yīng)用無(wú)效的問(wèn)題。
3. 注意點(diǎn)
第二小節(jié)的步驟2中的意思是:將頁(yè)面中所有不需要打印的元素隱藏,特別注意像模態(tài)窗Model這些元素,也要為它們加上 'print-hide'className屬性。
如果需要在特定位置強(qiáng)制分頁(yè)打印,可以嘗試在對(duì)應(yīng)元素上設(shè)置page-break-before:always !important、page-break-after:always !importantCSS屬性,該屬性只對(duì)塊級(jí)元素有效。
進(jìn)入打印預(yù)覽后,我們無(wú)法獲知用戶(hù)最終是選擇了打印,還是選擇了取消。這里若有人知道解決方法的話(huà),歡迎留言。

總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Electron整合React使用搭建開(kāi)發(fā)環(huán)境的步驟詳解
這篇文章主要介紹了Electron整合React使用搭建開(kāi)發(fā)環(huán)境,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2020-06-06
React實(shí)現(xiàn)反向代理和修改打包后的目錄
這篇文章主要介紹了React實(shí)現(xiàn)反向代理和修改打包后的目錄方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
深入理解react-router 路由的實(shí)現(xiàn)原理
這篇文章主要介紹了深入理解react-router 路由的實(shí)現(xiàn)原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
在React中強(qiáng)制重新渲染的4 種方式案例代碼
這篇文章主要介紹了在React中強(qiáng)制重新渲染的4 種方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-12-12
react 報(bào)錯(cuò)Module build failed: Browserslis
這篇文章主要介紹了react 報(bào)錯(cuò)Module build failed: BrowserslistError: Unknown browser query `dead`問(wèn)題的解決方法,需要的朋友可以參考下2023-06-06
React性能優(yōu)化的實(shí)現(xiàn)方法詳解
react憑借virtual DOM和diff算法擁有高效的性能,除此之外也有很多其他的方法和技巧可以進(jìn)一步提升react性能,在本文中我將列舉出可有效提升react性能的幾種方法,幫助我們改進(jìn)react代碼,提升性能2023-01-01

