如何利用html2Canvas截图,非页面元素,并解决因长度问题导致截图不完整的情况

1,016 阅读1分钟

浅谈一下如何解决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截图
   }
 );
}
};
    

欢迎各位大佬来点评