Skip to content

如何使用JavaScript将文本复制到剪贴板?

在构建网站时,非常常见的需求之一是能够通过单击按钮将文本复制到剪贴板。在现代浏览器中,使用异步的Clipboard API可以很容易地以编程方式实现这一点。然而,如果您需要支持旧版浏览器,则有一种替代选项,但稍微复杂一些。

异步的Clipboard API

截至撰写本文时(2024年1月),Clipboard API的完全支持还没有到位,但至少可以使用它来写入剪贴板。幸运的是,这已经足够了。尽管存在一些支持限制,但这是推荐的复制文本到剪贴板的方式,因为它提供了一种简单且安全的解决方案。

您只需要确保NavigatorNavigator.clipboardNavigator.clipboard.writeText是真值,然后调用Clipboard.writeText()将值复制到剪贴板即可。如果出现任何问题,您可以使用Promise.reject()返回一个立即拒绝的Promise,并保持返回类型一致。

const copyToClipboard = str => {
  if (navigator && navigator.clipboard && navigator.clipboard.writeText)
    return navigator.clipboard.writeText(str);
  return Promise.reject('Clipboard API不可用。');
};

如果您担心浏览器的支持情况,可以使用Promise.prototype.catch()来处理错误并提供一个回退方案。回退方案甚至可以使用下面将要介绍的旧方法。

使用Document.execCommand('copy')

尽管对于Clipboard API的支持在各个浏览器中都相当高,但如果您需要支持旧版浏览器,可能需要一个回退方案。如果是这种情况,您可以使用Document.execCommand('copy')来实现。以下是一个快速的步骤指南:

  1. 创建一个要附加到文档中的<textarea>元素。将其值设置为要复制到剪贴板的字符串。
  2. <textarea>元素附加到当前HTML文档,并使用CSS将其隐藏以防止闪烁。
  3. 使用Selection.getRangeAt()存储所选范围(如果有)。
  4. 使用HTMLInputElement.select()选择<textarea>元素的内容。
  5. 使用Document.execCommand('copy')<textarea>的内容复制到剪贴板。
  6. 从文档中删除<textarea>元素,并恢复用户之前的选择(如果有)。
const copyToClipboard = str => {
  const el = document.createElement('textarea');
  el.value = str;
  el.setAttribute('readonly', '');
  el.style.position = 'absolute';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  const selected =
    document.getSelection().rangeCount > 0
      ? document.getSelection().getRangeAt(0)
      : false;
  el.select();
  document.execCommand('copy');
  document.body.removeChild(el);
  if (selected) {
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(selected);
  }
};

[!CAUTION]

这种方法不会在所有地方都起作用,只有在用户操作的结果下才会起作用(例如在click事件监听器内部)。这是一种安全措施,以防止恶意网站在未经用户同意的情况下复制敏感数据到剪贴板上。