如何使用JavaScript的API 以编程方式将内容复制到剪贴板

274 阅读5分钟

简介

复制/粘贴功能无疑是现代计算机中最常用的功能之一,它是指将文本或图像从基于计算机的应用程序的一个部分复制/转移到另一个部分的过程。最近,以编程方式将一些内容复制到用户的剪贴板上,使他们不必这样做,这已成为普遍做法。

例如,在一个页面或电子邮件上弹出的激活和验证码。你可以自动复制它们,也可以有一个按钮,让别人把内容复制到剪贴板上,这样他们就不必自己去复制。此外,代码片段是你可能希望复制到剪贴板上的内容的一个很好的例子!

在本指南中,我们将看看如何使用JavaScript的新剪贴板API,以编程方式将内容复制到剪贴板。

**注意:除非你是在localhost ,否则新的 剪贴板API只有当你的网站托管在一个安全的域(HTTPS)上时才会起作用。

在JavaScript中复制到剪贴板

整个过程可以简化为一个触发代码的按钮(或其他元素)!你可以在页面上进行复制。你也可以在页面加载时这样做,但一般来说,当涉及到与用户自动对接并执行影响其本地机器的操作时(如添加东西到剪贴板),最好还是保守一点。

<textarea id="content"></textarea>
<button onclick="copyToClipboard()">Copy</button>

<script>
  function copyToClipboard() {
    var copyText = document.getElementById("content").value;
    navigator.clipboard.writeText(copyText).then(() => {
        // Alert the user that the action took place.
        // Nobody likes hidden stuff being done under the hood!
        alert("Copied to clipboard");
    });
  }
</script>

然而,这里有更多的东西要讲--它是如何工作的,有哪些限制,如何复制图片,等等。在本指南的其余部分,我们将准确地介绍这些内容。

在此之前,JavaScript开发者依赖于document.execCommand() 。然而,最近发布了一个相对较新的剪贴板API,使通过复制/粘贴的数据传输变得天衣无缝

读取浏览器的权限

根据你使用Clipboard API执行的操作(读或写),在尝试任何操作之前,最好先检查浏览器的权限。为了检查你是否有的权限,你将使用navigator.permissions ,并查询clipboard-write 的权限。

navigator.permissions.query({ name: "clipboard-write" }).then((result) => {
  if (result.state == "granted" || result.state == "prompt") {
    alert("Write access ranted!");
  }
});

同样地,你也可以检查你是否有clipboard-read 的权限。

navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
  if (result.state == "granted" || result.state == "prompt") {
    alert("Read access ranted!");
  }
});

将文本复制到剪贴板上

让我们先把文本复制到剪贴板上。我们在第一个例子中已经简单地看到了这一点,其实也没有比这更复杂的了。为了用新的剪贴板API复制文本,我们使用一个异步的writeText() 方法,这个方法只接受一个参数--要复制到剪贴板的文本。

由于是异步的,它返回一个承诺,如果剪贴板被成功更新,它将被解析,否则将被拒绝。

navigator.clipboard.writeText("TEXT_TO_COPY_TO").then(() => {
  /* Resolved - text copied to clipboard */
},() => {
  /* Rejected - clipboard failed */
});

读取剪贴板内容

与写作类似,你也可以读取剪贴板的内容。这确实引起了隐私问题,你应该通过各种方式透明和谨慎地使用这个功能。你可能想把写和读连在一起,以确保你读到的只是你已经写过的内容。

例如--一个用户可能在一个页面上打开一个验证码,这个验证码会自动复制到剪贴板上。如果你确保他们随后会带着剪贴板上的条目去另一个页面--你可以读取该条目并将其粘贴到另一个字段中,再次为他们节省一点时间和精力

我们使用readText() 方法来读取剪贴板上的最新条目。这个方法还返回一个承诺,如果浏览器可以访问剪贴板的内容,这个承诺就会被解决,否则就被拒绝。

navigator.clipboard
  .readText()
  .then((copiedText) => {
        // Do something with copied text
   });

与写入剪贴板不同,要求读取浏览器剪贴板内容会额外显示一个一次性的提示,要求用户同意,如下图所示。

Browser prompt

复制图片和富文本到剪贴板

丰富的文本指的是允许造型的文本内容,例如--粗体斜体和下划线,以及不同的字体家族和字体大小。当复制文本内容时,它可能是富文本格式的,这意味着有更多关于内容的元数据,而不仅仅是文本本身。

我们也可以使用剪贴板API的write() 方法来复制任意的数据,如富文本和图像,这个函数只接受一个参数,即一个包含要写入剪贴板的数据的数组。writeText() 方法是专门针对纯文本的,而write() 可以写入任何任意的数据。

例如,你可以从一个远程URL中获取一张图片,并将其复制到剪贴板。

const copyImage = async () => {
    const response = await fetch("/path/to/image.png");
    const blob = await response.blob();
    await navigator.clipboard.write([
      new ClipboardItem({ "image/png": blob }),
    ]);
  };

上面的例子也适用于复制富文本,当你把项目的类型改为"text/html"

const copyRichText = async () => {
    const content = document.getElementById("richTextInputId").innerHTML;
    const blob = new Blob([content], { type: "text/html" });
    const richTextInput = new ClipboardItem({ "text/html": blob });
    await navigator.clipboard.write([richTextInput]);
};

这确实假定richTextInputId 元素本身支持富文本。

从剪贴板读取图像和富文本

剪贴板API还提供了一个独特的read() 方法,用于读取任意数据而不是纯文本,它的工作原理与之前的readText() 函数类似,但可以读取任意数据。例如,读取先前复制到剪贴板上的图像数据。

<img src="" alt="" id="sample-img" />
<script>
const img = document.getElementById("sample-img");
  navigator.clipboard.read().then((data) => {
  for (let i = 0; i < data.length; i++) {
    if (!data[i].types.includes("image/png")) {
      // Clipboard does not contain image data
    } else {
      data[i].getType("image/png").then((blob) => {
          img.src = URL.createObjectURL(blob);
      });
    }
  }
});
</script>

结论

在这个简短的指南中,我们已经能够涵盖使用新的剪贴板API将文本和其他数据(如图像)复制到剪贴板的过程。无论何时,当你向用户的本地机器写入或读出时--要注意过程的透明性和安全性!