今天要写一个打印,以前写过是直接调用window.print() ,因为之间是点击预览,跳转页面,打印,所以也没发现有什么副作用,今天,打印是在当前页打印局部,网上部分方法说,打印前把body赋值成局部元素,打印后复原,我发现这样会让打印之后,页面点击事件失效
但是我找到一个无副作用的,是在取到全局dom,后把自己不需要的元素给隐藏掉,然后打印,因为拿到dom后赋值给了变量,直接操作变量,所以也不会影响原页面, 还可以自定义打印时候,打印样式,代码如下
把下面的代码是封装的,你只需要,新建一个文件,命名为print.ts/print.js(当然了名字你可以随便起),然后把下面代码赋值进去
export default function printHtml(html) { let style = getStyle(); let container = getContainer(html); document.body.appendChild(style); document.body.appendChild(container); getLoadPromise(container).then(() => { window.print(); document.body.removeChild(style); document.body.removeChild(container); }); } // 设置打印样式 function getStyle() { let styleContent = ` #print-container { display: none; } @media print { body > :not(.print-container) { display: none; } html, body { display: block !important; } #print-container { display: block; } //DetialContentCss 到 .contentTitle2都是我自己的样式,所以你也可以在这里写你打印的元素的样式 .DetialContentCss { border: 1px solid #333; padding: 20px; margin: 0 20px; .contentTitle { font-size: 22px; text-align: center; } .formCss{ display: flex; align-items: center; justify-content: space-around; margin: 40px 80px; } } .contentTitle2 { font-size: 14px; margin: 10px 0px; padding: 0 4px; display: flex; align-items: center; justify-content: space-between; } } `; let style = document.createElement("style"); style.innerHTML = styleContent; return style; } // 清空打印内容 function cleanPrint() { let div = document.getElementById('print-container') if (!!div) { document.querySelector('body').removeChild(div) } } // 新建DOM,将需要打印的内容填充到DOM function getContainer(html) { cleanPrint() let container = document.createElement("div"); container.setAttribute("id", "print-container"); container.innerHTML = html; return container; } // 图片完全加载后再调用打印方法 function getLoadPromise(dom) { let imgs = dom.querySelectorAll("img"); imgs = [].slice.call(imgs); if (imgs.length === 0) { return Promise.resolve(); } let finishedCount = 0; return new Promise(resolve => { function check() { finishedCount++; if (finishedCount === imgs.length) { resolve(); } } imgs.forEach(img => { img.addEventListener("load", check); img.addEventListener("error", check); }) }); }
然后打印页面引入使用一下,下面是你的打印页面的代码
//引入 import printHtml from "./helper/print" //使用 function clickPrint(){ //获取要打印的元素,你可以用id,然后用原生方法通过id去拿元素,我是vue3,直接使用了ref let print = tsPrint.value.innerHTML; printHtml(print) }
参考大佬地址