在 Safari 浏览器中直接使用 navigator.clipboard.writeText 是可以直接复制的,没有问题,但是如果在一个 promise 后使用 navigator.clipboard.writeText 就会报一个没有权限的错误,具体错误如下
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 得到复制的内容。
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 的支持。但支持多键值对的数据。
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。
const data = new ClipboardItem({
'text/plain': new Promise((resolve) => {
resolve(new Blob(['example text'], { type: 'text/plain' }))
})
})
粘贴:从剪切板读取数据#
readText()
要从剪贴板读取文本,可以调用 readText ()。
async function getClipboardText() {
try {
const text = await navigator.clipboard.readText();
console.log(`粘贴内容: ${text}`);
// 一些操作
} catch (e) {
console.error(`从剪切板获取数据失败: ${e}`);
}
}
read()
read () 返回 ClipboardItems 对象的列表。要从剪贴板读取图像,可通过遍历 ClipboardItems 列表来获取。
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 监听。
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