【问题标题】:Async Clipboard API "ClipboardItem is not defined" - Reactjs copy image to Clipboard异步剪贴板 API“ClipboardItem 未定义” - Reactjs 将图像复制到剪贴板
【发布时间】:2021-04-06 04:55:08
【问题描述】:

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

const response = await fetch('valid img url of a png image');
const blob = await response.blob();
await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob})]);

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

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

import React from "react";
  
function TestingClipAPI () { 

  async function handleScreenshot () {
    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})]);
  };
  
  return (
    <div>
     <button onClick={handleScreenshot} id="buttonID">test</button>
    </div>
  )
};

export default TestingClipAPI;

可能的问题:这可能是因为 CRA(Create-React-App)配置 - similar issue。可以完成库linked 之类的操作,创建一个画布并从那里复制图像。

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

const { ClipboardItem } = window;

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

【问题讨论】:

    标签: reactjs image npm clipboard webapi


    【解决方案1】:

    要寻找的东西:

    1. 浏览器支持Clipboard
    2. HTTPS 或 localhost 上的安全源。 See this post.
    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>
    );
    

    inline function 和以下是替代方案之间存在权衡。我个人会使用后一种方法。

    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>
    );
    

    最后,您可以返回chained promise

    【讨论】:

    • 谢谢你!我很欣赏你的评论。我考虑过浏览器不支持它,但我有 Chrome 的最新版本,如果我没有读错 MDN 上的信息,它应该支持它,并且我使用 npm start 在端口/本地主机 3000 中运行它。我听从你的建议尝试一下,会进一步了解它。
    • 我需要看看你是如何设置和调用你的复制函数的。您能否更新您的帖子以仅使用复制和粘贴功能以及返回浏览器的 JSX 来显示整个组件。
    • 当然伙计,我刚刚创建了一个测试组件,它与 copy-img-clipboard 库一起工作得很好。我推迟了我的回答,因为我还测试了它使我的本地主机安全,但它又失败了。
    • 我更新了anwser-onClicks 默认不是异步的。
    • 谢谢老兄!我接受你的建议。我通常以链式方式使用承诺,如果它比尝试更好,你知道或有意见吗?同步的 onClick 似乎不是这里的问题,我用这种方式进行了测试,首先重写了我的代码,然后在出现拼写错误的情况下复制了你的代码,并以同样的方式失败。我还有另一个 onClick 事件,只需使句柄函数异步即可获取并正常工作。非常感谢你,我很感激你的努力,我想你也开始发痒了
    【解决方案2】:

    只需在 ClipboardItem 前面添加窗口,如下所示

    window.ClipboardItem(...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-01
      • 2023-03-11
      • 2011-04-19
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 1970-01-01
      相关资源
      最近更新 更多