window.print —— 浏览器打印扫盲
博客地址jsonz1993.github.io/2018/06/win…
github 欢迎start follow
近日有个需求是做页面打印的,趁这个机会补一下比较冷门的浏览器打印知识。本文只讨论 Chrome、Safari、Firefox浏览器的情况。
打印接口
首先浏览器打印是一个很成熟的应用~ 至少是很早就已经有应用的功能,所以不会有什么兼容问题
最简单的打印就是直接调用 window.print(),当然用 document.execCommand('print') 也可以达到同样的效果。
这时候在Safari和Chrome都会弹起打印预览的窗口,FireFox没有预览而是直接让你选择打印机,OSx下可以通过预览PDF来预览~
一般这种直接在网页上调用 print 的方法是没办法满足我们的业务需求,比如说:
- 调整布局和字体大小来适应A4纸
- 打印的时候用不同的样式风格
- 使用更高清的图片来打印
- 某一些不相关的东西不出现在打印中等等等等
那么有哪些方法可以帮助我们改善打印的用户体验呢?
使用 print style sheet (打印样式表)
我们可以在 link 上加上一个 media="print" 来标识这是打印机才会应用的样式表, 如:
<link href="/example.css" media="print" rel="stylesheet" />
复制代码 这样打印的时候,就会默认将该样式表应用到文档中
使用媒介查询
兼容性: IE9+ 其他主流浏览器都支持 当我们要修改的样式没有那么多的时候,其实完全不需要重新写个样式表,只要写上一个媒介查询也可以达到同样的效果,如:
h1 {font-size: 14px;
}
@media print {h1 {font-size: 20px;}
}
复制代码 事件监听
beforeprint && afterprint
有两个事件可以监听到到打印事件,一个是beforeprint,一个是afterprint,分别表示打印事件触发前后。 这个事件在 IE6 就已经支持了,不过一点都不惊讶~ 毕竟IE很早就支持很多接口调用,之前好像做过IE打开Excel的需求~ 兼容大概是 Firefox、IE全支持, Chrome63+支持, Safari暂不支持,算是一半一半吧。
window.addEventListener('beforeprint', ()=> {document.body.innerHTML = '正在打印...';
});
window.addEventListener('afterprint', ()=> {document.body.innerHTML = '打印完成...';
});
复制代码 window.matchMedia 测试媒体查询接口
如果你想要兼容Safari或许可以试一下 window.matchMedia 兼容是 IE10+,其他主流浏览器完全没问题。
这个的用法稍微有点不一样,首先创建一个MediaQueryList对象,再通过他监听变化,如:
const printMedia = window.matchMedia('print');
function printChange({ matches, }) {document.body.innerHTML = matches? '正在打印...': '打印完成/取消';
}
printMedia.addListener(printChange);
复制代码 更加个性化定制打印区域/打印内容
如果项目上用的是jq等,或者想简单粗暴的打印某个区域又不想重新写样式表啊,什么的。 最傻瓜版的方式就是直接用jq插件 jQuery.print
也可以自己写一个去处理,大概的思路是创建一个iframe,把要打印的dom和样式表都丢进去,再调用iframe的打印事件。 这里写一个简单的 demo
function printPartial(dom, { title= document.title,}= {}) {if (!dom) return;let copyDom = document.createElement('span');const styleDom = document.querySelectorAll('style, link, meta');const titleDom = document.createElement('title');titleDom.innerText = title;copyDom.appendChild(titleDom);Array.from(styleDom).forEach(item=> {copyDom.appendChild(item.cloneNode(true));});copyDom.appendChild(dom.cloneNode(true));const htmlTemp = copyDom.innerHTML;copyDom = null;const iframeDom = document.createElement('iframe');const attrObj = {height: 0,width: 0,border: 0,wmode: 'Opaque'};const styleObj = {position: 'absolute',top: '-999px',left: '-999px',};Object.entries(attrObj).forEach(([key, value])=> iframeDom.setAttribute(key, value));Object.entries(styleObj).forEach(([key, value])=> iframeDom.style[key] = value);document.body.insertBefore(iframeDom, document.body.children[0]);const iframeWin = iframeDom.contentWindow;const iframeDocs = iframeWin.document;iframeDocs.write(``);iframeDocs.write(htmlTemp);iframeWin.focus();iframeWin.print();document.body.removeChild(iframeDom);
}printPartial(document.querySelector('#description'));
复制代码 最后一些注意的事情
- 打印会打印document下所有可见元素, 包括
里面的 - 背景都不会被打印出来,包括背景色啊背景图片啊等等
- 如果图片是懒加载的,需要特殊处理,不然打印的时候会直接空白
参考:
blog.csdn.net/fengshuiyue…
Mozilla print
Mozilla Using_a_print_style_sheet
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
