简介
复制/粘贴功能无疑是现代计算机中最常用的功能之一,它是指将文本或图像从基于计算机的应用程序的一个部分复制/转移到另一个部分的过程。最近,以编程方式将一些内容复制到用户的剪贴板上,使他们不必这样做,这已成为普遍做法。
例如,在一个页面或电子邮件上弹出的激活和验证码。你可以自动复制它们,也可以有一个按钮,让别人把内容复制到剪贴板上,这样他们就不必自己去复制。此外,代码片段是你可能希望复制到剪贴板上的内容的一个很好的例子!
在本指南中,我们将看看如何使用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
});
与写入剪贴板不同,要求读取浏览器剪贴板内容会额外显示一个一次性的提示,要求用户同意,如下图所示。

复制图片和富文本到剪贴板
丰富的文本指的是允许造型的文本内容,例如--粗体、斜体和下划线,以及不同的字体家族和字体大小。当复制文本内容时,它可能是富文本格式的,这意味着有更多关于内容的元数据,而不仅仅是文本本身。
我们也可以使用剪贴板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将文本和其他数据(如图像)复制到剪贴板的过程。无论何时,当你向用户的本地机器写入或读出时--要注意过程的透明性和安全性!