在 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