Async Clipboard API 的 SVG 支援

Async Clipboard API 的 Clipboard 介面,可提供讀取和寫入系統剪貼簿內容的讀取和寫入權限。這可讓網頁應用程式實作剪下、複製和貼上功能。您可以呼叫 read() 方法,將剪貼簿中的資料貼到應用程式,然後呼叫 write() 方法將資料複製到剪貼簿。除了採用可攜式網路圖形 (PNG) 格式的文字圖片、經過清理及未經處理的 HTML網頁自訂格式之外,Async Clipboard API 現在也支援複製及貼上 SVG 圖片,也就是說,您最終還能以更自然的方式,使用 SVG 圖片編輯軟體,不必以圖片形式複製及貼上 SVG,而再以 SVG 形式複製及貼上 SVG 圖片,

支援 SVG 的功能偵測

呼叫靜態 ClipboardItem.supports() 方法並傳遞所需的 MIME 類型,即可偵測對 SVG 圖片 (以及其他 MIME 類型) 的支援。

const supportsSVG = () => {
  if (
    !('supports' in window.ClipboardItem) ||
    !window.ClipboardItem.supports('image/svg+xml')
  ) {
    return false;
  }
  return true;
};

複製 SVG 圖片

使用物件填入 ClipboardItem,以複製 SVG 圖片。含有 SVG 圖片資料的 blob 是該值,而 blob 的類型 (在本例中為 'image/svg+xml') 做為索引鍵。

copyButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  try {
    const blob = await fetch(img.src).then((response) => response.blob());
    await navigator.clipboard.write([
      new window.ClipboardItem({
        [blob.type]: blob,
      }),
    ]);
  } catch (err) {
    console.error(err.name, err.message);
    alert(err.message);
  }
});

貼上 SVG 圖片

如要貼上 SVG 圖片,請從剪貼簿讀取 ClipboardItem,然後使用 getType() 方法取得所需的類型 (在本例中為 'image/svg+xml')。這會傳回一個 blob。轉換為 blob 網址後,您即可指派給 <img>src 屬性。

pasteButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  const [clipboardItem] = await navigator.clipboard.read();
  const svgBlob = await clipboardItem.getType('image/svg+xml');
  if (!svgBlob) {
    alert('No SVG in the clipboard.');
    return;
  }
  const image = document.createElement('img');
  const blobURL = URL.createObjectURL(svgBlob);
  image.addEventListener('load', () => {
    URL.revokeObjectURL(blobURL);
  });
  image.src = blobURL;
});

清理

SVG 是功能強大的格式,例如允許嵌入指令碼。假如使用者貼上不明來源的內容,瀏覽器可能會執行清理步驟。複製資料時,Async Clipboard API 會產生格式正確的 SVG 文件,然後將文件寫入剪貼簿。貼上資料時,片段剖析器會產生經過嚴格處理的 SVG 片段。因此,在執行貼上作業之前,onclick 事件處理常式屬性仍存在,但會在貼上後移除。

macOS 上的 Clipboard Viewer 應用程式檢查剪貼簿內容。顯示 SVG 中的點擊事件監聽器屬性仍然存在。
macOS 的 Clipboard Viewer 應用程式正在檢查剪貼簿內容。顯示 SVG 中的點擊事件監聽器屬性仍然存在。

操作示範

在 Glitch 的示範中,瞭解如何複製及貼上可擴充向量圖形。請參閱原始碼,瞭解運作方式。請務必在複製及貼上之前和之後,試著點選任一圓圈。貼上之後,疑似危險的 onclick 事件處理常式屬性都會遭到移除。

特別銘謝

Chromium 中對 Async Clipboard API 的 SVG 支援是由 Microsoft Edge 團隊實作。這則貼文是由 Rachel Andrew 和 Anupam Snigdha 審核。