您好,登錄后才能下訂單哦!
這篇文章主要講解了“JavaScript圖片打印功能怎么實(shí)現(xiàn)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“JavaScript圖片打印功能怎么實(shí)現(xiàn)”吧!
其實(shí)瀏覽器 window 對(duì)象提供了 print 方法,就可以對(duì)整個(gè)頁(yè)面進(jìn)行打印。只需要點(diǎn)擊按鈕執(zhí)行以下方法即可。
window.print()
調(diào)用此方法,會(huì)打印出整個(gè) html 里的內(nèi)容,即 document 對(duì)象下所有的頁(yè)面節(jié)點(diǎn)。而我們需要的是只打印頁(yè)面的某個(gè)元素部分,即只打印圖片。
很遺憾,瀏覽器在 具體的dom 節(jié)點(diǎn)上并沒(méi)有部署 print 方法,不過(guò)我們可以轉(zhuǎn)變個(gè)思路,我們可以將需要打印的元素提取出來(lái),同時(shí)構(gòu)造一個(gè)新的window對(duì)象,將提取出來(lái)的元素插入到這個(gè)window對(duì)象下,再調(diào)用打印即可。
<button @click="print">打印</button> <div id="box"> <img src="/test.jpg"/> </div>
例如我們只需要打印id="box"下的 img
print(){ const el = document.querySelector("#box") var newWindow=window.open("打印窗口","_blank"); var docStr = el.innerHTML; newWindow.document.write(docStr); newWindow.document.close(); newWindow.print(); newWindow.close(); },
通過(guò) window.open 方式返回一個(gè)新的 window 對(duì)象,再調(diào)用 document.write 寫(xiě)入我們獲取到指定節(jié)點(diǎn),再打印即可。
這種方式有點(diǎn)不好的就是需要重新開(kāi)一個(gè) window ,并且設(shè)置一些打印的樣式會(huì)比較麻煩。所以不推薦。
我查閱了一些知名的打印插件,都是采用的 iframe
來(lái)構(gòu)造頁(yè)面來(lái)實(shí)現(xiàn)局部打印的。iframe 有個(gè)屬性 srcdoc
可以渲染指定的html內(nèi)容
<iframe srcdoc="<p>Hello world!</p>"></iframe>
以往我們都是通過(guò)src來(lái)加載一個(gè)指定的頁(yè)面地址,這里通過(guò) srcdoc 來(lái)渲染指定的html內(nèi)容。下面實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的點(diǎn)擊按鈕打印圖片功能:
// 打印 function btnClick(){ const iframe = document.createElement('iframe') // 視覺(jué)上隱藏 iframe iframe.style.height = 0 iframe.style.visibility = 'hidden' iframe.style.width = 0 const str = `<html> <style media='print'> @page{size:A4 landscape};margin:0mm;padding:0} </style> <body> <div id="box"></div> </body> </html> ` iframe.setAttribute('srcdoc', str); document.body.appendChild(iframe); // 一定要加載完成后執(zhí)行 iframe.addEventListener("load",()=>{ const image = document.querySelector('img').cloneNode(); image.style.display = 'block' const box = iframe.contentDocument.querySelector('#box'); box.appendChild(image); // 一定要圖片加載完再打印 image.addEventListener('load', function () { // 打印 iframe.contentWindow.print(); }); }) iframe.contentWindow.addEventListener('afterprint', function () { iframe.parentNode.removeChild(iframe); }); }
對(duì)于打印的樣式設(shè)置,可以通過(guò)在style標(biāo)簽上添加media=print
來(lái)設(shè)置
<style media='print'> @page{size:A4 landscape};margin:0mm;padding:0} </style>
上述就指定了打印機(jī)默認(rèn)格式為A4紙張 橫向打印 ,margin設(shè)置成0毫米是為了保證不出現(xiàn)頁(yè)眉頁(yè)腳。
基礎(chǔ)功能的打印實(shí)現(xiàn)了,可是為了讓打印體驗(yàn)更好,產(chǎn)品經(jīng)理又提出了需求點(diǎn):
當(dāng)圖片是橫圖時(shí),即寬度大于高度的圖片時(shí),需要將A4紙張橫向打印,然后圖片在A4里面上下左右都居中。同時(shí)要將這張圖片盡可能地鋪滿A4紙張,也不能改變圖片的寬高比(即不變形)。
當(dāng)圖片是縱圖時(shí),即寬度小于高度的圖片時(shí),需要將A4紙張縱向打印,然后圖片在A4里面上下左右都居中。同時(shí)要將這張圖片盡可能地鋪滿A4紙張,也不能改變圖片的寬高比(即不變形)。
圖片不要緊挨著紙張邊緣,留出一定邊距。
實(shí)現(xiàn)思路: 由于要保證紙張邊緣留有一定的空白區(qū)域,這個(gè)時(shí)也可以使用 margin 來(lái)實(shí)現(xiàn)。
<style media='print'> @page{size:A4 landscape;margin:10mm;} </style>
但是不將 margin 設(shè)置成 0 的話,又會(huì)默認(rèn)出現(xiàn)頁(yè)眉頁(yè)腳。這顯然是矛盾的。這個(gè)時(shí)候我想到了一個(gè)好的思路,就是將圖片放置到一個(gè) div 容器里,這個(gè) div 寬高設(shè)置成 A4 一樣的大小。同時(shí)將div里面的圖片通過(guò) flex 布局來(lái)實(shí)現(xiàn)上下左右都居中。然后打印區(qū)域設(shè)置成這個(gè)容器就可以了。
由于 div 和 A4 紙張一樣大,所以 @page 里可以設(shè)置成 margin:0mm 來(lái)規(guī)避頁(yè)眉頁(yè)腳的出現(xiàn)。然后里面的圖片需要居中
// 獲取圖片寬高比 const rate = owidth/oheight // 橫圖的話容器寬度就是A4的高度,即29.7cm,縱圖的話寬度就是21cm,由于剛好設(shè)置成21cm會(huì)溢出,多出一張紙,原因未明,所以我設(shè)置成20.9 const boxWidthCM = `${rate >1 ? 29.7 : 20.9}cm` // 容器高度 const boxHeightCM = `${rate >1 ? 20.9 : 29.7}cm` const str = `<html> <style media='print'> @page{size:A4 ${rate>1 ? 'landscape':'portrait'};margin:0mm;padding:0} </style> <style> *{padding:0;margin:0} body{height:100%} #box{ width:${boxWidthCM}; height:${boxHeightCM}; display:flex; align-items:center; justify-content:center; } </style> <body> <div id="box"></div> </body> </html>` iframe.setAttribute('srcdoc', str);
居中問(wèn)題解決了,接下來(lái)就是解決圖片盡可能鋪滿紙張問(wèn)題。這個(gè)時(shí)候我們需要結(jié)合容器大小以及圖片寬高比來(lái)手動(dòng)計(jì)算圖片寬高,算法如下:
let imgW = null; let imgH = null; if(rate > 1){ // 橫圖 if(rate>1.414){ imgW = 29.7 imgH = 29.7/rate } else { imgH = 20.9 imgW = 20.9*rate } } else { if(rate>(1/1.414)){ imgW = 20.9 imgH = 20.9/rate } else { imgH = 29.7 imgW = 29.7*rate } } // 預(yù)留1cm邊距 imgW = imgW - 1 imgH = imgW/rate iframe.addEventListener("load",()=>{ const image = document.createElement("img") image.style.width = item.width image.style.height = item.height image.style.display = 'block' image.src = item.newUrl || item.url || item.original_content_url image.style.width = `${imgW}cm` image.style.height = `${imgH}cm` const box = iframe.contentDocument.querySelector('#box'); box.appendChild(image); image.addEventListener('load', function () { iframe.contentWindow.print(); }); })
完整代碼:
print(item){ const { owidth,oheight,height } = item const rate = owidth/oheight const imgHeight = height.replace("px","") const iframe = document.createElement('iframe') iframe.style.height = 0 iframe.style.visibility = 'hidden' iframe.style.width = 0 const boxWidthCM = `${rate >1 ? 29.7 : 20.9}cm` const boxHeightCM = `${rate >1 ? 20.9 : 29.7}cm` let imgW = null; let imgH = null; if(rate > 1){ // 橫圖 if(rate>1.414){ imgW = 29.7 imgH = 29.7/rate } else { imgH = 20.9 imgW = 20.9*rate } } else { if(rate>(1/1.414)){ imgW = 20.9 imgH = 20.9/rate } else { imgH = 29.7 imgW = 29.7*rate } } // 預(yù)留1cm邊距 imgW = imgW - 1 imgH = imgW/rate const str = `<html> <style media='print'> @page{size:A4 ${rate>1 ? 'landscape':'portrait'};margin:0mm;padding:0} </style> <style> *{padding:0;margin:0} body{height:100%} #box{ width:${boxWidthCM}; height:${boxHeightCM}; display:flex; align-items:center; justify-content:center; } </style> <body> <div id="box"></div> </body> </html>` iframe.setAttribute('srcdoc', str); document.body.appendChild(iframe); iframe.addEventListener("load",()=>{ const image = document.createElement("img") image.style.width = item.width image.style.height = item.height image.style.display = 'block' image.src = item.newUrl || item.url || item.original_content_url image.style.width = `${imgW}cm` image.style.height = `${imgH}cm` const box = iframe.contentDocument.querySelector('#box'); box.appendChild(image); image.addEventListener('load', function () { iframe.contentWindow.print(); }); }) iframe.contentWindow.addEventListener('afterprint', function () { iframe.parentNode.removeChild(iframe); }); }
感謝各位的閱讀,以上就是“JavaScript圖片打印功能怎么實(shí)現(xiàn)”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)JavaScript圖片打印功能怎么實(shí)現(xiàn)這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。