Clipboard:write() 方法
>Clipboard 接口的 write() 方法用于将任意 ClipboardItem 数据(如图像和文本)写入剪贴板,返回一个在操作完成时兑现的 Promise。该方法可用于实现剪切和复制功能。
该方法理论上可以写入任意数据(与只能写入文本的 writeText() 不同)。浏览器通常支持写入文本、HTML 和 PNG 图像数据。
语法
write(data)
参数
data-
包含要写入剪贴板的数据的
ClipboardItem对象数组。
返回值
一个在数据写入剪贴板后兑现的 Promise。注意:如果底层操作系统不支持系统剪贴板上的多个原生剪贴板项,则只会写入数组中的第一个 ClipboardItem。
如果无法写入剪贴板,则 promise 将会被拒绝。
异常
NotAllowedErrorDOMException-
如果不允许写入剪贴板,则抛出此异常。
安全考虑
只能在安全上下文中读取剪贴板。
其他安全要求在 API 概述主题的安全考虑一节中进行了介绍。
示例
>写入文本到剪贴板
本示例函数在按钮被点击时,将指定字符串写入剪贴板,替换当前内容。对于这一情况,你也可以直接使用 Clipboard.writeText() 方法。
button.addEventListener("click", () => writeClipboardText("示例文本"));
async function setClipboard(text) {
const type = "text/plain";
const clipboardItemData = {
[type]: text,
};
const clipboardItem = new ClipboardItem(clipboardItemData);
await navigator.clipboard.write([clipboardItem]);
}
setClipboard() 函数在 type 常量中指定了 MIME 类型为 "text/plain",然后指定包含单一属性的 clipboardItemData 对象——键为 MIME 类型,而值为我们想要写入剪贴板的文本内容。我们随后构造了一个新的 ClipboardItem 对象并传入 clipboardItemData 对象。
最后,我们使用 await 调用 write() 方法以写将数据写入剪贴板。
将 canvas 内容写入剪贴板
本示例在 canvas 上绘制一个蓝色矩形。点击该矩形即可将 canvas 的内容作为图片复制到剪贴板,然后可以在其他元素中粘贴该图片。
HTML
HTML 定义了 <canvas> 元素和用于粘贴图片的 id 为 target 的 <div> 元素。
<canvas id="canvas" width="100" height="100"></canvas>
<div id="target">在此粘贴。</div>
const logElement = document.querySelector("#log");
function log(text) {
logElement.innerText = `${logElement.innerText}${text}\n`;
logElement.scrollTop = logElement.scrollHeight;
}
JavaScript
首先定义一个 async 函数将 canvas 转为 blob。该函数将旧的回调式 HTMLCanvasElement.toBlob() 方法封装为更直观的基于 Promise 的函数。
// 用 async/await 替代 toBlob() 回调
async function getBlobFromCanvas(canvas) {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
if (blob) {
resolve(blob);
} else {
reject(new Error("Canvas toBlob 操作执行失败"));
}
});
});
}
接下来设置 canvas 并添加 click 事件监听器。
点击蓝色矩形时,canvas 的内容会被复制为 blob,然后通过 ClipboardItem 写入剪贴板。
const canvas = document.getElementById("canvas");
// 设置 canvas
const ctx = canvas.getContext("2d");
ctx.fillStyle = "cornflowerblue";
ctx.fillRect(0, 0, 100, 100);
canvas.addEventListener("click", copyCanvasContentsToClipboard);
const target = document.getElementById("target");
async function copyCanvasContentsToClipboard() {
// 复制 canvas 到 blob
try {
const blob = await getBlobFromCanvas(canvas);
// 用 blob 及其类型创建 ClipboardItem 并写入数组
const data = [new ClipboardItem({ [blob.type]: blob })];
// 写入剪贴板
await navigator.clipboard.write(data);
log("已复制");
} catch (error) {
log(error);
}
}
注意:如果你要写入不常见的文件类型,或无法提前确定类型,建议使用 ClipboardItem.supports() 检查类型是否受支持,并提供用户友好的错误提示。
然后为目标元素添加 paste 事件监听器,将剪贴板内容以图片形式显示。通过 FileReader API 的 readAsDataUrl 方法读取 blob 并创建 <img> 元素:
target.addEventListener("paste", (event) => {
const items = (event.clipboardData || window.clipboardData).items;
const blob = items[0].getAsFile();
const reader = new FileReader();
reader.addEventListener("load", (event) => {
const img = new Image();
img.src = event.target.result;
target.appendChild(img);
});
reader.readAsDataURL(blob);
});
结果
效果如下。首先点击蓝色方块,然后选中“在此粘贴”文本,并使用操作系统的粘贴快捷键(如 Windows 下的 Ctrl+V)。
规范
| 规范 |
|---|
| Clipboard API and events> # dom-clipboard-write> |