Clipboard API：全新的异步复制、粘贴API

在 Safari 浏览器中直接使用 navigator.clipboard.writeText 是可以直接复制的，没有问题，但是如果在一个 promise 后使用 navigator.clipboard.writeText 就会报一个没有权限的错误，具体错误如下

Copy
Unhandled Rejection (NotAllowedError): The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

原因：

因为开发中的复制内容是由接口请求的，safari 会拒绝此操作，由于安全限制，上述方法只能在用户与页面进行交互的情况下才能正常工作。如果您的复制操作不是由用户触发的（例如，通过定时器或其他非交互方式），则可能会受到浏览器的限制。

而 document.execCommand () 访问剪贴板是同步的，只能读写 DOM

Clipbo ard API

全新的异步复制、粘贴 API。它提供（如果用户授予权限）对系统剪贴板内容的读取和写入访问权限。 Clipboard API 可用于在 Web 应用程序中实现剪切、复制和粘贴功能，只需调用 writeText 方法就可以成功复制一段文本。此 API 旨在取代使用document.execCommand访问剪贴板。

复制：将内容写入剪切板

writeText()

将文本写入系统剪贴板，可以调用 writeText ()。此时文本已复制成功，可以使用 Ctrl+V 得到复制的内容。

Copy
async function copyText(text) {
try {
await navigator.clipboard.writeText(text)
console.log('页面内容已复制到剪贴板 ')
} catch (e) {
console.log(`复制文案失败: ${e}`)
}
}

write()

实际上，writeText () 只是通用 write () 方法的一种简写，它还允许您将图像复制到剪贴板。
图像复制成功后，需通过 read () 方法读取。
write () 方法接收参数为 ClipboardItem 对象数组。
创建一个新的 ClipboardItem 对象，需以 MIME 类型为键，以 Blob 为值。

目前未实现对多个 ClipboardItems 的支持。但支持多键值对的数据。

Copy
const data = new ClipboardItem({
// [MIME]: Blob
'image/png': Blob,
'text/plain': Blob
})
// 支持
await navigator.clipboard.write([data]);
// 不支持
await navigator.clipboard.write([data, data]);

注意：由于 Clipboard API 还属于实验性 API ，所以在 Safari 浏览器中表现有所不同.

必须在 https 环境才能调试使用。否则报错。NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

ClipbordItem 的 blob 属性值需要返回一个 Promise。

Copy
const data = new ClipboardItem({
'text/plain': new Promise((resolve) => {
resolve(new Blob(['example text'], { type: 'text/plain' }))
})
})

粘贴：从剪切板读取数据

readText()

要从剪贴板读取文本，可以调用 readText ()。

Copy
async function getClipboardText() {
try {
const text = await navigator.clipboard.readText();
console.log(`粘贴内容: ${text}`);
// 一些操作
} catch (e) {
console.error(`从剪切板获取数据失败: ${e}`);
}
}

read()

read () 返回 ClipboardItems 对象的列表。要从剪贴板读取图像，可通过遍历 ClipboardItems 列表来获取。

Copy
async function getClipboardContents () {
try {
const clipboardItems = await navigator.clipboard.read() // clipboardItems列表
for (const clipboardItem of clipboardItems) {
// types: ClipboardItem 中可用的 MIME 类型数组。
for (const type of clipboardItem.types) {
// 返回使用请求的 MIME 类型的 Blob 解析的 Promise。
// 如果未找到 MIME 类型，则返回错误。
const blob = await clipboardItem.getType(type)
if (type === 'text/plain') { // 文本
// Blob 接口中的 text() 方法返回一个 Promise.
// 该 Promise 使用包含 Blob 内容的字符串进行解析，解释为 UTF-8。
const text = await blob.text()
console.log(text)
} else if (type === 'image/png') { // 图片
const url = URL.createObjectURL(blob)
console.log(url)
}
}
}
} catch (e) {
console.error(`粘贴失败: ${e}` )
}
}

监听事件

Clipboard API 继承自 EventTarget (一个 DOM 接口，由可以接收事件、并且可以创建侦听器的对象实现)，因此它也有监听事件。测试还未发现如何监听事件，目前可以使用之前的 document.addEventListener 监听。

Copy
document.addEventListener('paste', async (e) => {
e.preventDefault();
// 多内容或者图像内容
getClipboardContents()

// 当只有文本时
if (navigator.clipboard) {
text = await navigator.clipboard.readText();
}
else {
text = e.clipboardData.getData('text/plain'); // 早期写法
}
});

此文由 Mix Space 同步更新至 xLog
原始链接为 https://liu-wb.com/posts/default/clipboard