文章目录
- 文章参考
- 问题描述
- 使用chrome保存图片功能——验证问题3
- 测试代码
- 测试结果
- 测试结论
- 使用浏览器打印功能为pdf
- 打印的API
- 通用JS代码——将网页总具体的某段保存为pdf
- 天坑——为什么我打印的时候只显示当前页
- 禁止页面打印
- 样式在class中,如何获取DOM的样式?
- ele.style
- getComputedStyle()
文章参考
- 原生js获取元素样式的简单方法
问题描述
- 工作中,想把网页中某段内容保存图片
- 想保存的这部分内容在网页中的某个div中,并且出现了滚动条,
(不是窗口出现滚动条,是某个div有滚动条)
- 第一想法是使用chrome的保存图片的命令功能 —— 保存全屏、某个节点、当前可视区域三个功能,但是测试没有成功(这个功能只是针对显示在html节点的内容,因为节点高度固定,所以保存的图片就是我们看到的部分)
- 想到“网页打印功能”,将打印的内容保存为Pdf,还方便查找
使用chrome保存图片功能——验证问题3
测试代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div style="height: 200px;width: 200px;overflow: auto;"><div>dddddddd</div><div>dddddddd</div><div>此处省略一万行代码</div></div>
</body>
</html>
测试结果
保存固定高度节点为图片的内容,如图
测试结论
这个功能只是针对显示在html节点的内容,因为节点高度固定,所以保存的图片就是我们看到的部分
使用浏览器打印功能为pdf
打印的API
window.print()
document.execCommand('print')
上面两种API 作用是一样的
通用JS代码——将网页总具体的某段保存为pdf
(function dayin(queryStr) {// 防止页面设置了禁止打印的功能var style=document.createElement("style");style.innerText = "@media print{body{display:block!important;}}"document.getElementsByTagName("html")[0].append(style)var userAgent = navigator.userAgent.toLowerCase() // 取得浏览器的userAgent字符串if (userAgent.indexOf('trident') > -1) {alert('请使用google或者360浏览器打印')return false} else if (userAgent.indexOf('msie') > -1) {alert('请使用google或者360浏览器打印')return false} else {// 其它浏览器使用lodop// var oldstr = window.document.body.outerHTMLvar printData = window.document.querySelector(queryStr).outerHTML // 获得 div 里的所有 html 数据,因为只有样式没有事件// window.document.body.innerHTML = printDataconst htmlObj = window.document.getElementsByTagName('html')[0]const bodyObj = window.document.getElementsByTagName('body')[0]// 缓存body、html的高度const beforeBodyHeightStyle = getComputedStyle(bodyObj).heightconst beforeHtmlHeightStyle = getComputedStyle(htmlObj).height// 缓存body、html是否隐藏起来了const beforeBodyOverflowStyle = getComputedStyle(bodyObj).overflowconst beforeHtmlOverflowStyle = getComputedStyle(htmlObj).overflowconsole.log(beforeBodyOverflowStyle)// 防止 html 和 Body都设置了高度为100%,因为实际要打印的高度是所有内容,大于浏览器的高度100%的,而我们查看的内容和显示的内容都是浏览器的高度,并且有滚动条,这样就让我们有错觉,// 我们打印的内容是html的高度的内容,不是100%,有可能是小于100%,也可能大于100%的htmlObj.style.height = 'auto'bodyObj.style.height = 'auto'// 判断body是否隐藏不显示滚动条if (beforeBodyOverflowStyle === 'hidden') {bodyObj.style.overflow = 'auto'}if (beforeHtmlOverflowStyle === 'hidden') {htmlObj.style.overflow = 'auto'}//var targetDiv = document.createElement('div')const targetId = Math.floor(Math.random() * 10000000000000000)targetDiv.id = targetIdtargetDiv.innerHTML = printData // 将 HTML 代码作为字符串重新拷贝到 创建的div 中// document.getElementById('app').style.display = 'none'var docfrag = document.createDocumentFragment() // 创建一个fragment 对象// 将 body 下面的所有非 link 和 script 标签的全部都移动到 创建的 fragment 对象中for (let i = 0; i < bodyObj.childNodes.length; i++) {var node = bodyObj.childNodes[i]// 过滤 text 节点、script 节点if (node.nodeType === 1 &&node.nodeName !== 'LINK' &&node.nodeName !== 'SCRIPT') {console.log(node.nodeName)// 如果参数节点是 DOM 已经存在的节点,appendChild方法会将其从原来的位置,移动到新位置。docfrag.appendChild(node)}}bodyObj.append(targetDiv)// window.print()// 等价于window.document.execCommand('print')htmlObj.style.height = beforeHtmlHeightStylebodyObj.style.height = beforeBodyHeightStyleif (beforeBodyOverflowStyle === 'hidden') {bodyObj.style.overflow = 'hidden'}if (beforeHtmlOverflowStyle === 'hidden') {htmlObj.style.overflow = 'hidden'}// 打印结束后,放开隐藏内容targetDiv.remove()var children = docfrag.childNodes // NodeList 接口console.log(children instanceof NodeList)children.forEach((node, i, list) => {console.log(node, i, list)})bodyObj.appendChild(docfrag)}})("article.article");
打印的思路
- 将节点的代码缓存起来
将body内部的 非 LINK 和 非SCRIPT 节点 缓存起来,放到 新建的 fragment 节点中
- 将需要打印的代码创建为 一个DIV 节点,挂在 body 节点下面
- 检测是否固定了html和body的高度
- 检测是否将html和body设置了overflow:hidden
打印完成或者取消打印,将创建的打印节点删除,然后将新建的fragment 下的节点重新返回挂载到 body 节点下面
天坑——为什么我打印的时候只显示当前页
上面的代码我做了注释,再重复说明一下,下面的情况是我遇到的一种情况,具体情况具体分析
- 防止 html 和 Body都设置了高度为100%,因为实际要打印的高度是所有内容,大于浏览器的高度100%的,
- 而我们查看的内容和显示的内容都是浏览器的高度,并且有滚动条,这样就让我们有错觉,
- 结论:
我们打印的内容是html的实际高度的内容,不是100%
,有可能是小于100%,也可能大于100%的
禁止页面打印
@media print{body{display:none!important;}
}
样式在class中,如何获取DOM的样式?
问题描述:
在学习DOM的时候就看到通过ele.style来获取元素样式值,但是有时候获取的并非是节点的样式值,而是空值。
ele.style
a. 这是因为ele.style只能获取写在元素标签中的style属性里的样式值,
b. 无法获取到定义在<style></style>和通过<link href="css.css">加载进来的样式属性
var test = document.getElementById("test");
//获取节点的color
test.style.color;
getComputedStyle()
getComputedStyle是一个可以获取当前元素所有最终使用的CSS属性值。
window.getComputedStyle("元素", "伪类");