Javascript 反应-如何将图像复制到剪贴板?
我正在使用react web app,需要实现的功能之一是在单击时复制图像,以便用户可以将其粘贴到:绘画、文字等 我尝试了几种方法,首先是按照本文中详细的说明进行操作: 这就是我想到的(containerId指的是一个div元素,它包含一个image元素作为它的第一个子元素): 没用。 我尝试在此处实施标有2颗星的解决方案: 但是createControlRange()未定义 我尝试使用navigator.clipboard api,但它只适用于png,而该应用程序适用于jpg 我寻找了一个npm库,可以完成这一点,但我发现所有的文本复制。 NPM类似:将副本复制到剪贴板 任何帮助都将不胜感激 编辑1: 按照dw_uuu说明,这是我想到的: (注意:我必须npm安装babel polyfill并将其导入App.js,以使异步函数工作并传递此错误:未定义regeneratorRuntime) 代码到达复制的图像消息,但在将其粘贴到word上时仍不显示。另一件事是我 控制台错误:未捕获(承诺中)DOMEExceptionJavascript 反应-如何将图像复制到剪贴板?,javascript,html,reactjs,image,copy-paste,Javascript,Html,Reactjs,Image,Copy Paste,我正在使用react web app,需要实现的功能之一是在单击时复制图像,以便用户可以将其粘贴到:绘画、文字等 我尝试了几种方法,首先是按照本文中详细的说明进行操作: 这就是我想到的(containerId指的是一个div元素,它包含一个image元素作为它的第一个子元素): 没用。 我尝试在此处实施标有2颗星的解决方案: 但是createControlRange()未定义 我尝试使用navigator.clipboard api,但它只适用于png,而该应用程序适用于jpg 我寻找了一个np
您可以使用
navigator.clipboard.write
函数异步复制img(src){
const img=等待获取(src);
const imgBlob=等待img.blob();
试一试{
navigator.clipboard.write([
新剪贴簿({
'image/png':imgBlob,//相应地更改图像类型
})
]);
}捕获(错误){
控制台错误(error);
}
}
基于@Zohaib Ijaz的答案和文章
如果图像是jpeg/jpg,它将首先使用HTML5画布将图像转换为png
函数createImage(选项){
选项=选项| |{};
常量img=(图像)?新图像():document.createElement(“img”);
if(options.src){
img.src=options.src;
}
返回img;
}
函数convertToPng(imgBlob){
const imageUrl=window.URL.createObjectURL(imgBlob);
const canvas=document.createElement(“canvas”);
const ctx=canvas.getContext(“2d”);
const imageEl=createImage({src:imageUrl});
imageEl.onload=(e)=>{
canvas.width=e.target.width;
canvas.height=e.target.height;
ctx.drawImage(e.target,0,0,e.target.width,e.target.height);
canvas.toBlob(copyToClipboard,“image/png”,1);
};
}
异步函数copyImg(src){
const img=等待获取(src);
const imgBlob=等待img.blob();
if(src.endsWith(“.jpg”)| | src.endsWith(“.jpeg”)){
convertToPng(imgBlob);
}else if(src.endsWith(“.png”)){
复制剪贴板(imgBlob);
}否则{
控制台错误(“不支持格式”);
}
}
异步函数copyToClipboard(pngBlob){
试一试{
等待navigator.clipboard.write([
新剪贴簿({
[pngBlob.type]:pngBlob
})
]);
控制台日志(“图像复制”);
}捕获(错误){
控制台错误(error);
}
}
功能copyImageViaSelector(选择器){
copyimgdocument.querySelector(selector.src);
}
复制图像
您可以尝试此操作。您需要为此提供一个HTMLLevel
它通常是对某个div的引用
<div ref={node => (this._imageRef = node)}>
<img src=""/>
</div>
您需要向函数提供此_imageRef
现在所有这些都应该起作用了
export function copyImageToClipboard(element) { // element is an ref to the div here
const selection = window.getSelection();
const range = document.createRange();
const img = element.firstChild ;
// Preserve alternate text
const altText = img.alt;
img.setAttribute('alt', img.src);
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
try {
// Security exception may be thrown by some browsers.
return document.execCommand('copy');
} catch (ex) {
console.warn('Copy to clipboard failed.', ex);
return false;
} finally {
img.setAttribute('alt', altText);
}
}
注意:这在IE中也适用如果您有输入错误,应该是
异步函数
。如果图像在同一个域上,这应该有效,或者在禁用CORS的域上。网站图像是jpg而不是png。然后使用image/jpg
Write-type-image/jpeg-not-supported
。很遗憾,我编辑了这个问题。但还是不行。也许是因为你提到的同一个领域。虽然听起来很奇怪:图像已经在客户端浏览器中,但CORS与此有什么关系?CORS可能是一个问题,因为我们正在通过ajax再次下载图像(如果图像已经加载到页面上,它将从缓存中获取)。但错误与此无关。@UNlessofficialchannel更新了原始函数并添加了React示例。(async/await在copyToClipboard
函数中丢失)这不起作用。@YTG,这个例子在这里或像JSFIDLE这样的网站上不起作用,因为iFrame需要设置“剪贴板写入”权限。将copyToClipboard
更改为copyService.copyToClipboard
,并createImage({src:imageUrl})
tocopyService.createImage({src:imageUrl})
哪一行触发了Uncaught in promise
error?navigator.clipboard.write此JSFIDLE对您有效吗?FIDLE也无效。行:navigator.clipboard.write抛出DomeException:文档未聚焦。此外,react示例也失败了。我想这是因为照片来自fiddler api。我在这里尝试过,但我无法将其粘贴到slack或stackoverflow中。澳大利亚国立大学的建议?
copyImg = async (imgElementId) => {
const imgElement = document.getElementById(imgElementId);
const src = imgElement.src;
const img = await fetch(src);
const imgBlob = await img.blob();
if (src.endsWith(".jpg") || src.endsWith(".jpeg")) {
copyService.convertToPng(imgBlob);
} else if (src.endsWith(".png")) {
copyService.copyToClipboard(imgBlob);
} else {
console.error("Format unsupported");
}
}
convertToPng = (imgBlob) => {
const imageUrl = window.URL.createObjectURL(imgBlob);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const imageEl = createImage({ src: imageUrl });
imageEl.onload = (e) => {
canvas.width = e.target.width;
canvas.height = e.target.height;
ctx.drawImage(e.target, 0, 0, e.target.width, e.target.height);
canvas.toBlob(copyToClipboard, "image/png", 1);
};
}
createImage = (options) => {
options = options || {};
const img = (Image) ? new Image() : document.createElement("img");
if (options.src) {
img.src = options.src;
}
return img;
}
copyToClipboard = (pngBlob) => {
try {
navigator.clipboard.write([
new ClipboardItem({
[pngBlob.type]: pngBlob
})
]);
console.log("Image copied");
} catch (error) {
console.error(error);
}
}
<div ref={node => (this._imageRef = node)}>
<img src=""/>
</div>
constructor(props) {
super(props);
this._imageRef = null;
}
export function copyImageToClipboard(element) { // element is an ref to the div here
const selection = window.getSelection();
const range = document.createRange();
const img = element.firstChild ;
// Preserve alternate text
const altText = img.alt;
img.setAttribute('alt', img.src);
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
try {
// Security exception may be thrown by some browsers.
return document.execCommand('copy');
} catch (ex) {
console.warn('Copy to clipboard failed.', ex);
return false;
} finally {
img.setAttribute('alt', altText);
}
}