grit

grit

剪貼簿 API:全新的異步複製、貼上 API

在 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.

原因:

  1. 因為開發中的複製內容是由介面請求的,safari 會拒絕此操作,由於安全限制,上述方法只能在用戶與頁面進行交互的情況下才能正常工作。如果您的複製操作不是由用戶觸發的(例如,通過定時器或其他非交互方式),則可能會受到瀏覽器的限制。
  2. 而 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 瀏覽器中表現有所不同.

  1. 必須在 https 環境才能調試使用。否則報錯。NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
  2. 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


載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。