我的使用情况是:我有一个网站编辑和提供自己的网页的用户列表。在此列表中的每个页面由一个缩略图来表示。每次用户使用编辑器对页面进行更改时,都必须更新相应站点的缩略图以反映更改。我做的方式是通过安装在页面中ThumbnailSandbox组件,从终极版店里传递的道具,然后使用DOM至PNG创建截图,并在列表中使用它。但我想这样做没有安装页面上的部件,因为我认为这将是一个更清洁的解决方案,并受着其他交互发生的机会较少。因此,我创建了一个CodeSanbox来说明我要实现的目标。
我的逻辑是这样的:
import React from "react";
import ReactDOMServer from "react-dom/server";
import html2canvas from "html2canvas";
import MyComp from "./component.jsx";
export const createScrenshot = () => {
const el = (
<div>
test component <MyComp />
</div>
);
const markup = ReactDOMServer.renderToString(el);
let doc = new DOMParser().parseFromString(markup, "text/html");
let target = doc.body.getElementsByClassName("my-comp")[0];
console.log(markup, target);
html2canvas(target, {
useCORS: true,
allowTaint: true,
scale: 1,
width: 500,
height: 500,
x: 0,
y: 0,
logging: true,
windowWidth: 500,
windowHeight: 500
})
.then(function(canvas) {
console.log(">> ", canvas);
})
.catch(error => {
console.log(error);
});
};
因此,我将组件传递给ReactDOM,然后使用第一步中的字符串创建一个DOM节点,并将该节点传递给html2canvas。但是这时我得到了错误Uncaught TypeError: Cannot read property 'pageXOffset' of null
。由于传递给html2canvas元素的ownerDocument为null,并且它不具有的属性:devicePixelRation,innerWidth,innerHeight,pageYOffset和pageXOffset。据我了解,那是因为node元素不是DOM的一部分。
现在,我的问题是:
1)是否有来解决使用这个问题html2canvas?
的方式2)是否有任何其他的方式,采取的阵营部件,在浏览器中,屏幕截图,而不在DOM安装部件?
提前谢谢!
答案 0 :(得分:0)
对于点1:
为什么不安装组件,然后在处理后删除引用中的组件? (也可以在ComponentDidMount中完成,但引用会在DidMount之前出现)。这是执行下载(创建标签并单击然后将其删除)的最标准解决方案。
这是使用ref回调的未经测试的示例代码
export class CreateScrenshot extends React.Component {
constructor() {
super() {
this._reactRef = this._reactRef.bind(this);
this.state = {
removeNode: false
};
}
}
_reactRef(node) {
if(node) {
// your html2Canvas handling and in the returned promise remove the node by
this.setState({removeNode: true});
}
}
render() {
let childComponent = null;
if(!this.state.removeNode) {
{/*pass the ref of the child node to the parent component using the ref callback*/}
childComponent = (
<div>
test component <MyComp refCallBack={this._reactRef}/>
</div>
);
}
return childComponent;
}
}
但是,限制是这将是异步的并且可能导致闪烁。 因此,如果可能,请尝试使用同步库,以便可以在下一个渲染中删除该节点。
对于点2:https://reactjs.org/docs/react-component.html#componentdidmount
来自react的componentDidMount()doc部分: “但是,对于模态和工具提示之类的情况,当您需要在渲染取决于其大小或位置的对象之前测量DOM节点时,这是必要的。”
这很清楚,您只能在安装节点后才能获得它们的测量值。
答案 1 :(得分:0)
将react元素设置为z-index,底部为-9999px