异步剪贴板 API“ClipboardItem 未定义” - Reactjs 将图像复制到剪贴板

And*_*s S 8 clipboard image npm reactjs webapi

我正在研究 React js,我使用 npm 通过 create-react-app 创建了我的应用程序。我试图构建一个按钮来获取图像并将其写入剪贴板。幸运的是,我发现这个npm 库似乎工作得很好!但我一直在思考为什么我不能使用\xc2\xbfbuilt-in? 用于复制图像的异步剪贴板 API(文本复制工作正常)。我在这里读了一本非常有启发性的指南,并在这里继续阅读其他很棒的指南,所以我尝试了那里和其他页面中建议的所有代码(尽管它们似乎并没有真正改变功能,但我必须尝试)。我在每次尝试时都遇到了同样的错误,阻碍了编译:“\'ClipboardItem\'未定义 no-undef ”。例如,一个代码是这样的:

\n
const response = await fetch(\'valid img url of a png image\');\nconst blob = await response.blob();\nawait navigator.clipboard.write([new ClipboardItem({ \'image/png\': blob})]);\n\n
Run Code Online (Sandbox Code Playgroud)\n

它看起来很简单,很容易遵循。问题是,当您需要将数据放入剪贴板可以读取的表单中,使其成为一个 blob 时,因为我需要 ClipboardItem 构造函数,而我的应用程序似乎无法识别它。当然,不断返回 ClipboardItem 未定义,或者如果我以某种方式定义它,则表示它不是构造函数。我尝试使用其他构造函数,例如 Blob(),但遇到了同样的问题。最后一件事让我一直在思考,由于我是编程世界的新手,如果有一些基本的东西我不知道 Web API 与 Node 或 Reactjs 的交互,以及是否有一个当然是解决方案!提前谢谢你们,你们太棒了!

\n

编辑:根据要求添加整个组件代码:

\n
import React from "react";\n  \nfunction TestingClipAPI () { \n\n  async function handleScreenshot () {\n    const response = await fetch(\'https://i.postimg.cc/d0hR8HfP/telefono.png\');\n    const blob = await response.blob();\n    await navigator.clipboard.write([new ClipboardItem({ \'image/png\': blob})]);\n  };\n  \n  return (\n    <div>\n     <button onClick={handleScreenshot} id="buttonID">test</button>\n    </div>\n  )\n};\n\nexport default TestingClipAPI;\n
Run Code Online (Sandbox Code Playgroud)\n

可能的问题:这可能是因为 CRA (Create-React-App) 配置 -类似问题。像图书馆链接之类的东西操作,创建画布并从那里复制图像。

\n

解决方案或使其正常工作的方法:在使用 ClipboardItem 之前以这种方式进行调用:

\n
const { ClipboardItem } = window;\n
Run Code Online (Sandbox Code Playgroud)\n

注意:这也适用于其他具有相同问题的构造函数,例如 toBlob 和 HTMLCanvasElement。

\n

Jon*_*der 7

不幸的是,截至本答案发布时,ClipboardItemFirefox 不支持。(可以通过设置启用支持about:config;但当然,大多数互联网用户不会这样做。)

来源:https ://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem#browser_compatibility


Sea*_*n W 2

寻找的东西:

  1. 浏览器支持剪贴板
  2. HTTPS 或本地主机上的安全源。 请参阅这篇文章。
  3. 如何调用该函数 - 在OP的情况下 - onClick 和异步。

问题是 onClick 默认情况下不是异步的,您没有等待响应,而且 navigator.clipboard 中也有拼写错误。

  const handleScreenshot = async () => {
    try {
      const response = await fetch(
        "https://i.postimg.cc/d0hR8HfP/telefono.png"
      );
      const blob = await response.blob();
      await navigator.clipboard.write([
        new ClipboardItem({ "image/png": blob }),
      ]);
    } catch (err) {
      console.error(err);
    }
  }

return (
  <button onClick={async () => await handleScreenshot()} id="buttonID">
    test
  </button>
);
Run Code Online (Sandbox Code Playgroud)

内联函数之间存在权衡,下面是替代方案。我个人会使用后一种方法。

function handleScreenshot() {
  async function screenShot() {
    try {
      const response = await fetch(
        "https://i.postimg.cc/d0hR8HfP/telefono.png"
      );
      const blob = await response.blob();
      await navigator.clipboard.write([
        new ClipboardItem({ "image/png": blob }),
      ]);
    } catch (err) {
      console.error(err);
    }
  }
  screenShot();
}

return (
  <button onClick={handleScreenshot} id="buttonID">
    test
  </button>
);
Run Code Online (Sandbox Code Playgroud)

最后,您可以返回一个链式 Promise