浅谈一下如何解决html2Canvas截图丢失异常问题。
众所周知,纯前端dom生成图片,html2Canvas是不二之选,但是我们在实际使用的时候总会出现奇奇怪怪的问题。例如dom长度过长,截图可能会存在dom丢失的情况。比如有的dom元素,我们在页面中是可以滚动的,这个时候我们如何去将这个dom完整的截取下来呢。
封装的方法
一个比较简单的实现深克隆dom节点的方法
const deepCloneELement = (
dom: HTMLElement | string
): HTMLElement => {
let div: HTMLDivElement | null =
document.createElement("div");
const str =
typeof dom == "string"
? dom
: dom.outerHTML;
div.innerHTML = str;
const returnDom = div.childNodes[0];
// console.log(str, "div");
div = null; // 通过标记法进行垃圾回收
return returnDom as HTMLElement;
};
思考
问题一:如何截取动态创建的document.createElement("div"),或者是通过string拼接出来的dom呢。
方案:
废话不多说直接进入正题,我们可以通过css的position absolute将dom转移或者克隆到屏幕外,配合zoom进行缩放,再截图即可规避截图不全的问题,建议zoom根据自己的需求进行动态计算。
// 这个时候需要用到我们上面封装的dom深克隆的方法。
import html2canvas from "html2canvas";
export const downPng = (
ref:
| React.RefObject<HTMLDivElement>
| string
) => {
if (
typeof ref === "string"
? ref
: ref.current
) {
let cloneDom: HTMLElement | null =
deepCloneELement(
typeof ref === "string"
? ref
: ref.current!
);
cloneDom.style.position =
"absolute";
cloneDom.style.top = "-10000px";
cloneDom.style.zIndex = "-100";
// 此处就是解决滚动窗口外出现截图不全的关键代码。建议zoom可以按照自己需求进行动态设置。本文先进行写死。
cloneDom.style.zoom = ".5";
document.body.appendChild(cloneDom);
html2canvas(cloneDom).then(
(canvas) => {
cloneDom!.remove(); //进行及时清理
cloneDom = null;
console.log(canvas);// 此时已经拿到了离屏的dom截图
}
);
}
};
欢迎各位大佬来点评