Created
May 31, 2016 09:37
-
-
Save ufologist/6864d941263c6cdf52294e1e70060704 to your computer and use it in GitHub Desktop.
html2canvas snapshot invisible DOM in a scrollable div
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>html2canvas snapshot invisible DOM in a scrollable div</title> | |
| <style> | |
| /* 为了在页面上能够更好地观察到 canvas 元素 */ | |
| html, | |
| body { | |
| height: 100%; | |
| } | |
| canvas { | |
| border: 1px dotted red; | |
| } | |
| /* 假设要快照的 DOM 元素的样式上有结构依赖 */ | |
| #container #snapshotme { | |
| color: red; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>html2canvas snapshot invisible DOM in a scrollable div</h1> | |
| <h2>要快照的 DOM 元素在滚动区域的底部</h2> | |
| <div id="container" style="height: 150px; border: 1px dashed #aaa; overflow: auto; position: relative;"> | |
| <div id="placeholder" style="height: 2000px;"></div> | |
| <p id="snapshotme"><strong>snapshotme</strong></p> | |
| </div> | |
| <p> | |
| 其他情况下都好好的, 为什么单单这种情况就有问题呢? | |
| 我猜测滚动区域内的 DOM 元素浏览器是"懒渲染"的, 既然还没有渲染出来, 那么就可以认为和 display:none 是一样的效果. | |
| 因此 html2canvas 获取这个 DOM 元素的像素数据时拿到的就会是一片空白了. | |
| </p> | |
| <h3>那么我们如何验证这个猜测呢? 就是要证实视野内可见元素才能快照到像素数据这个观点</h3> | |
| <ul> | |
| <li> | |
| <p>滚动 DIV 元素到一定位置, 才能获取到要快照元素的图形数据 <button onclick="snapshotDirect()">snapshotDirect</button></p> | |
| <p><em>不太灵活, 因为需要调整滚动条的位置</em></p> | |
| </li> | |
| <li> | |
| <p>clone 要快照的元素添加到 body 后再快照 <button onclick="snapshotClone2Body()">snapshotClone2Body</button></p> | |
| <p><em>更改了 DOM 结构, 因此如果要快照的 DOM 元素的样式上有结构依赖, 例如 #container #snapshotme {color: red;} 就会出现快照图片与样式不符的问题</em></p> | |
| </li> | |
| <li> | |
| <p>将快照的元素 absolute 后再快照 <button onclick="snapshotAbsolute()">snapshotAbsolute</button></p> | |
| <p><em>如果滚动页面, 让快照的元素(因为父级已经滚动出了视野范围)在视野以外, 还是会出现快照不到像素数据的问题</em></p> | |
| </li> | |
| <li> | |
| <p>将快照的元素 fixed 后再快照 <button onclick="snapshotFixed()">snapshotFixed</button></p> | |
| <p><em>由于 fixed 确保元素是跟着浏览器窗口的滚动条走的, 因此元素始终会在视野范围内始终可见</em></p> | |
| </li> | |
| </ul> | |
| <div style="height: 100%"></div> | |
| <script src="http://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script> | |
| <script> | |
| // https://github.com/niklasvh/html2canvas/issues/590 | |
| var snapshotme = document.getElementById('snapshotme'); | |
| function snapshotDirect() { | |
| html2canvas(snapshotme).then(function(canvas) { | |
| document.body.appendChild(canvas); | |
| }); | |
| } | |
| function snapshotClone2Body() { | |
| var cloneNode = snapshotme.cloneNode(true); | |
| document.body.appendChild(cloneNode); | |
| html2canvas(cloneNode).then(function(canvas) { | |
| document.body.removeChild(cloneNode); | |
| document.body.appendChild(canvas); | |
| }); | |
| } | |
| function snapshotAbsolute() { | |
| var rect = snapshotme.getBoundingClientRect(); | |
| snapshotme.style.position = 'absolute'; | |
| snapshotme.style.top = '0'; | |
| snapshotme.style.width = rect.width + 'px'; | |
| html2canvas(snapshotme).then(function(canvas) { | |
| snapshotme.style.position = ''; | |
| snapshotme.style.top = ''; | |
| snapshotme.style.width = ''; | |
| document.body.appendChild(canvas); | |
| }); | |
| } | |
| function snapshotFixed() { | |
| var rect = snapshotme.getBoundingClientRect(); | |
| snapshotme.style.position = 'fixed'; | |
| snapshotme.style.top = '0'; | |
| snapshotme.style.width = rect.width + 'px'; | |
| html2canvas(snapshotme).then(function(canvas) { | |
| snapshotme.style.position = ''; | |
| snapshotme.style.top = ''; | |
| snapshotme.style.width = ''; | |
| document.body.appendChild(canvas); | |
| }); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment